From patchwork Thu Mar 13 18:43:01 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hans de Goede X-Patchwork-Id: 14015787 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 1FBBC1EF393 for ; Thu, 13 Mar 2025 18:43:27 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741891410; cv=none; b=k8RPZ/279eHOFqG6skhs772cZrNtHFwtueKjLSyZ1QqV5RQFLc6Z2RyXBCCJpHE3CZg83c2fkB6HnwwUYTe+4oTIIQu138dTB+SkRWb5ApVKeo+AKH7MU5sQgTv4cfrCUNKoPEyksFumqrUK7REfxOwrWCr2emaE/3G2OQRZzxA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741891410; c=relaxed/simple; bh=1rXjGTK/51Qyyb3m7CsZXPWaQErFxrZlmcz4sAgWxk8=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=tZQIy8xUK+Jd5XeF2lbQ/+li3nDYYvUzopzDlLhM+HjTvKt8XeoiMRTEMxt7IcN4YoS4byLv9Sevb51BrVTP2iR4NyjO3kbyIR/S6QOJ6BuTCHS6rmtQd07U90oI5ZVT9qKzijbur3Z8ZvF/Nl8VMrZnSAYOepX1xnX9ws2ZOrc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=O4bwok1y; arc=none smtp.client-ip=170.10.133.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="O4bwok1y" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1741891407; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=hnC3MPy96OWR3s4eY5MHz+vNZtOPP2rBqFNP2pdWt48=; b=O4bwok1yQULRYxm+e6LiQbdjlWV7z4PoUlk8uVAZ2fjFNR5GtoUNftgcD5eNEjQcCymSDG 5uRnXL3guM4dsKJ6sAP9lbobClhD53iBxYBQd63QBs38nXAli3630heZG2h+7QWLgH/Vuh hbPzDNL9nAkBd3XTnRpA/Hdw81h1i0s= Received: from mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-640-GZv4laDYMgG9QlZFCgf73A-1; Thu, 13 Mar 2025 14:43:25 -0400 X-MC-Unique: GZv4laDYMgG9QlZFCgf73A-1 X-Mimecast-MFC-AGG-ID: GZv4laDYMgG9QlZFCgf73A_1741891403 Received: from mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.4]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 13711180034D; Thu, 13 Mar 2025 18:43:23 +0000 (UTC) Received: from shalem.redhat.com (unknown [10.45.224.5]) by mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id B7BC83003770; Thu, 13 Mar 2025 18:43:19 +0000 (UTC) From: Hans de Goede To: Sakari Ailus , Heimir Thor Sverrisson Cc: Hans de Goede , Stanislaw Gruszka , Ingvar Hagelund , Joachim Reichel , Bryan O'Donoghue , Hao Yao , Mauro Carvalho Chehab , linux-media@vger.kernel.org Subject: [PATCH v8 01/14] media: i2c: Add Omnivision OV02C10 sensor driver Date: Thu, 13 Mar 2025 19:43:01 +0100 Message-ID: <20250313184314.91410-2-hdegoede@redhat.com> In-Reply-To: <20250313184314.91410-1-hdegoede@redhat.com> References: <20250313184314.91410-1-hdegoede@redhat.com> Precedence: bulk X-Mailing-List: linux-media@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.4 From: Heimir Thor Sverrisson Add a new driver for the Omnivision OV02C10 camera sensor. This is based on the out of tree driver by Hao Yao from: https://github.com/intel/ipu6-drivers/blob/master/drivers/media/i2c/ov02c10.c This has been tested on a Dell XPS 9440 together with the IPU6 isys CSI driver and the libcamera software ISP code. Tested-by: Stanislaw Gruszka Tested-by: Ingvar Hagelund Tested-by: Heimir Thor Sverrisson Signed-off-by: Heimir Thor Sverrisson Link: https://lore.kernel.org/r/20250116232207.217402-1-heimir.sverrisson@gmail.com Signed-off-by: Hans de Goede --- drivers/media/i2c/Kconfig | 10 + drivers/media/i2c/Makefile | 1 + drivers/media/i2c/ov02c10.c | 1296 +++++++++++++++++++++++++++++++++++ 3 files changed, 1307 insertions(+) create mode 100644 drivers/media/i2c/ov02c10.c diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig index bb9ab2330d24..99a72b8ee45c 100644 --- a/drivers/media/i2c/Kconfig +++ b/drivers/media/i2c/Kconfig @@ -365,6 +365,16 @@ config VIDEO_OV02A10 To compile this driver as a module, choose M here: the module will be called ov02a10. +config VIDEO_OV02C10 + tristate "OmniVision OV02C10 sensor support" + select V4L2_CCI_I2C + help + This is a Video4Linux2 sensor driver for the OmniVision + OV02C10 camera. + + To compile this driver as a module, choose M here: the + module will be called ov02c10. + config VIDEO_OV08D10 tristate "OmniVision OV08D10 sensor support" help diff --git a/drivers/media/i2c/Makefile b/drivers/media/i2c/Makefile index a17151bb3d49..191c1f7c3f50 100644 --- a/drivers/media/i2c/Makefile +++ b/drivers/media/i2c/Makefile @@ -85,6 +85,7 @@ obj-$(CONFIG_VIDEO_OG01A1B) += og01a1b.o obj-$(CONFIG_VIDEO_OV01A10) += ov01a10.o obj-$(CONFIG_VIDEO_OV01A1S) += ov01a1s.o obj-$(CONFIG_VIDEO_OV02A10) += ov02a10.o +obj-$(CONFIG_VIDEO_OV02C10) += ov02c10.o obj-$(CONFIG_VIDEO_OV08D10) += ov08d10.o obj-$(CONFIG_VIDEO_OV08X40) += ov08x40.o obj-$(CONFIG_VIDEO_OV13858) += ov13858.o diff --git a/drivers/media/i2c/ov02c10.c b/drivers/media/i2c/ov02c10.c new file mode 100644 index 000000000000..291da9ee1788 --- /dev/null +++ b/drivers/media/i2c/ov02c10.c @@ -0,0 +1,1296 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (c) 2022 Intel Corporation. + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define OV02C10_LINK_FREQ_400MHZ 400000000ULL +#define OV02C10_SCLK 80000000LL +#define OV02C10_MCLK 19200000 +#define OV02C10_DATA_LANES 1 +#define OV02C10_RGB_DEPTH 10 + +#define OV02C10_REG_CHIP_ID CCI_REG16(0x300a) +#define OV02C10_CHIP_ID 0x5602 + +#define OV02C10_REG_STREAM_CONTROL CCI_REG8(0x0100) + +/* vertical-timings from sensor */ +#define OV02C10_REG_VTS CCI_REG16(0x380e) +#define OV02C10_VTS_MAX 0xffff + +/* Exposure controls from sensor */ +#define OV02C10_REG_EXPOSURE CCI_REG16(0x3501) +#define OV02C10_EXPOSURE_MIN 4 +#define OV02C10_EXPOSURE_MAX_MARGIN 8 +#define OV02C10_EXPOSURE_STEP 1 + +/* Analog gain controls from sensor */ +#define OV02C10_REG_ANALOG_GAIN CCI_REG16(0x3508) +#define OV02C10_ANAL_GAIN_MIN 0x10 +#define OV02C10_ANAL_GAIN_MAX 0xf8 +#define OV02C10_ANAL_GAIN_STEP 1 +#define OV02C10_ANAL_GAIN_DEFAULT 0x10 + +/* Digital gain controls from sensor */ +#define OV02C10_REG_DIGITAL_GAIN CCI_REG24(0x350a) +#define OV02C10_DGTL_GAIN_MIN 0x0400 +#define OV02C10_DGTL_GAIN_MAX 0x3fff +#define OV02C10_DGTL_GAIN_STEP 1 +#define OV02C10_DGTL_GAIN_DEFAULT 0x0400 + +/* Rotate */ +#define OV02C10_ROTATE_CONTROL CCI_REG8(0x3820) +#define OV02C10_ISP_X_WIN_CONTROL CCI_REG16(0x3810) +#define OV02C10_ISP_Y_WIN_CONTROL CCI_REG16(0x3812) +#define OV02C10_CONFIG_ROTATE 0x18 + +/* Test Pattern Control */ +#define OV02C10_REG_TEST_PATTERN CCI_REG8(0x4503) +#define OV02C10_TEST_PATTERN_ENABLE BIT(7) + +struct ov02c10_mode { + /* Frame width in pixels */ + u32 width; + + /* Frame height in pixels */ + u32 height; + + /* Horizontal timining size */ + u32 hts; + + /* Default vertical timining size */ + u32 vts_def; + + /* Min vertical timining size */ + u32 vts_min; + + /* Link frequency needed for this resolution */ + u32 link_freq_index; + + /* MIPI lanes used */ + u8 mipi_lanes; + + /* Sensor register settings for this resolution */ + const struct reg_sequence *reg_sequence; + const int sequence_length; +}; + +static const struct reg_sequence sensor_1928x1092_1lane_30fps_setting[] = { + {0x0301, 0x08}, + {0x0303, 0x06}, + {0x0304, 0x01}, + {0x0305, 0xe0}, + {0x0313, 0x40}, + {0x031c, 0x4f}, + {0x301b, 0xd2}, + {0x3020, 0x97}, + {0x3022, 0x01}, + {0x3026, 0xb4}, + {0x3027, 0xe1}, + {0x303b, 0x00}, + {0x303c, 0x4f}, + {0x303d, 0xe6}, + {0x303e, 0x00}, + {0x303f, 0x03}, + {0x3021, 0x23}, + {0x3501, 0x04}, + {0x3502, 0x6c}, + {0x3504, 0x0c}, + {0x3507, 0x00}, + {0x3508, 0x08}, + {0x3509, 0x00}, + {0x350a, 0x01}, + {0x350b, 0x00}, + {0x350c, 0x41}, + {0x3600, 0x84}, + {0x3603, 0x08}, + {0x3610, 0x57}, + {0x3611, 0x1b}, + {0x3613, 0x78}, + {0x3623, 0x00}, + {0x3632, 0xa0}, + {0x3642, 0xe8}, + {0x364c, 0x70}, + {0x365f, 0x0f}, + {0x3708, 0x30}, + {0x3714, 0x24}, + {0x3725, 0x02}, + {0x3737, 0x08}, + {0x3739, 0x28}, + {0x3749, 0x32}, + {0x374a, 0x32}, + {0x374b, 0x32}, + {0x374c, 0x32}, + {0x374d, 0x81}, + {0x374e, 0x81}, + {0x374f, 0x81}, + {0x3752, 0x36}, + {0x3753, 0x36}, + {0x3754, 0x36}, + {0x3761, 0x00}, + {0x376c, 0x81}, + {0x3774, 0x18}, + {0x3776, 0x08}, + {0x377c, 0x81}, + {0x377d, 0x81}, + {0x377e, 0x81}, + {0x37a0, 0x44}, + {0x37a6, 0x44}, + {0x37aa, 0x0d}, + {0x37ae, 0x00}, + {0x37cb, 0x03}, + {0x37cc, 0x01}, + {0x37d8, 0x02}, + {0x37d9, 0x10}, + {0x37e1, 0x10}, + {0x37e2, 0x18}, + {0x37e3, 0x08}, + {0x37e4, 0x08}, + {0x37e5, 0x02}, + {0x37e6, 0x08}, + + /* 1928x1092 */ + {0x3800, 0x00}, + {0x3801, 0x00}, + {0x3802, 0x00}, + {0x3803, 0x00}, + {0x3804, 0x07}, + {0x3805, 0x8f}, + {0x3806, 0x04}, + {0x3807, 0x47}, + {0x3808, 0x07}, + {0x3809, 0x88}, + {0x380a, 0x04}, + {0x380b, 0x44}, + {0x380c, 0x08}, + {0x380d, 0xe8}, + {0x380e, 0x04}, + {0x380f, 0x8c}, + {0x3810, 0x00}, + {0x3811, 0x02}, + {0x3812, 0x00}, + {0x3813, 0x02}, + {0x3814, 0x01}, + {0x3815, 0x01}, + {0x3816, 0x01}, + {0x3817, 0x01}, + + {0x3820, 0xb0}, + {0x3821, 0x00}, + {0x3822, 0x80}, + {0x3823, 0x08}, + {0x3824, 0x00}, + {0x3825, 0x20}, + {0x3826, 0x00}, + {0x3827, 0x08}, + {0x382a, 0x00}, + {0x382b, 0x08}, + {0x382d, 0x00}, + {0x382e, 0x00}, + {0x382f, 0x23}, + {0x3834, 0x00}, + {0x3839, 0x00}, + {0x383a, 0xd1}, + {0x383e, 0x03}, + {0x393d, 0x29}, + {0x393f, 0x6e}, + {0x394b, 0x06}, + {0x394c, 0x06}, + {0x394d, 0x08}, + {0x394e, 0x0b}, + {0x394f, 0x01}, + {0x3950, 0x01}, + {0x3951, 0x01}, + {0x3952, 0x01}, + {0x3953, 0x01}, + {0x3954, 0x01}, + {0x3955, 0x01}, + {0x3956, 0x01}, + {0x3957, 0x0e}, + {0x3958, 0x08}, + {0x3959, 0x08}, + {0x395a, 0x08}, + {0x395b, 0x13}, + {0x395c, 0x09}, + {0x395d, 0x05}, + {0x395e, 0x02}, + {0x395f, 0x00}, + {0x395f, 0x00}, + {0x3960, 0x00}, + {0x3961, 0x00}, + {0x3962, 0x00}, + {0x3963, 0x00}, + {0x3964, 0x00}, + {0x3965, 0x00}, + {0x3966, 0x00}, + {0x3967, 0x00}, + {0x3968, 0x01}, + {0x3969, 0x01}, + {0x396a, 0x01}, + {0x396b, 0x01}, + {0x396c, 0x10}, + {0x396d, 0xf0}, + {0x396e, 0x11}, + {0x396f, 0x00}, + {0x3970, 0x37}, + {0x3971, 0x37}, + {0x3972, 0x37}, + {0x3973, 0x37}, + {0x3974, 0x00}, + {0x3975, 0x3c}, + {0x3976, 0x3c}, + {0x3977, 0x3c}, + {0x3978, 0x3c}, + {0x3c00, 0x0f}, + {0x3c20, 0x01}, + {0x3c21, 0x08}, + {0x3f00, 0x8b}, + {0x3f02, 0x0f}, + {0x4000, 0xc3}, + {0x4001, 0xe0}, + {0x4002, 0x00}, + {0x4003, 0x40}, + {0x4008, 0x04}, + {0x4009, 0x23}, + {0x400a, 0x04}, + {0x400b, 0x01}, + {0x4077, 0x06}, + {0x4078, 0x00}, + {0x4079, 0x1a}, + {0x407a, 0x7f}, + {0x407b, 0x01}, + {0x4080, 0x03}, + {0x4081, 0x84}, + {0x4308, 0x03}, + {0x4309, 0xff}, + {0x430d, 0x00}, + {0x4806, 0x00}, + {0x4813, 0x00}, + {0x4837, 0x10}, + {0x4857, 0x05}, + {0x4500, 0x07}, + {0x4501, 0x00}, + {0x4503, 0x00}, + {0x450a, 0x04}, + {0x450e, 0x00}, + {0x450f, 0x00}, + {0x4800, 0x24}, + {0x4900, 0x00}, + {0x4901, 0x00}, + {0x4902, 0x01}, + {0x5000, 0xf5}, + {0x5001, 0x50}, + {0x5006, 0x00}, + {0x5080, 0x40}, + {0x5181, 0x2b}, + {0x5202, 0xa3}, + {0x5206, 0x01}, + {0x5207, 0x00}, + {0x520a, 0x01}, + {0x520b, 0x00}, + {0x365d, 0x00}, + {0x4815, 0x40}, + {0x4816, 0x12}, + {0x4f00, 0x01}, + /* plls */ + {0x0303, 0x05}, + {0x0305, 0x90}, + {0x0316, 0x90}, + {0x3016, 0x12}, +}; + +static const struct reg_sequence sensor_1928x1092_2lane_30fps_setting[] = { + {0x0301, 0x08}, + {0x0303, 0x06}, + {0x0304, 0x01}, + {0x0305, 0xe0}, + {0x0313, 0x40}, + {0x031c, 0x4f}, + {0x301b, 0xf0}, + {0x3020, 0x97}, + {0x3022, 0x01}, + {0x3026, 0xb4}, + {0x3027, 0xf1}, + {0x303b, 0x00}, + {0x303c, 0x4f}, + {0x303d, 0xe6}, + {0x303e, 0x00}, + {0x303f, 0x03}, + {0x3021, 0x23}, + {0x3501, 0x04}, + {0x3502, 0x6c}, + {0x3504, 0x0c}, + {0x3507, 0x00}, + {0x3508, 0x08}, + {0x3509, 0x00}, + {0x350a, 0x01}, + {0x350b, 0x00}, + {0x350c, 0x41}, + {0x3600, 0x84}, + {0x3603, 0x08}, + {0x3610, 0x57}, + {0x3611, 0x1b}, + {0x3613, 0x78}, + {0x3623, 0x00}, + {0x3632, 0xa0}, + {0x3642, 0xe8}, + {0x364c, 0x70}, + {0x365f, 0x0f}, + {0x3708, 0x30}, + {0x3714, 0x24}, + {0x3725, 0x02}, + {0x3737, 0x08}, + {0x3739, 0x28}, + {0x3749, 0x32}, + {0x374a, 0x32}, + {0x374b, 0x32}, + {0x374c, 0x32}, + {0x374d, 0x81}, + {0x374e, 0x81}, + {0x374f, 0x81}, + {0x3752, 0x36}, + {0x3753, 0x36}, + {0x3754, 0x36}, + {0x3761, 0x00}, + {0x376c, 0x81}, + {0x3774, 0x18}, + {0x3776, 0x08}, + {0x377c, 0x81}, + {0x377d, 0x81}, + {0x377e, 0x81}, + {0x37a0, 0x44}, + {0x37a6, 0x44}, + {0x37aa, 0x0d}, + {0x37ae, 0x00}, + {0x37cb, 0x03}, + {0x37cc, 0x01}, + {0x37d8, 0x02}, + {0x37d9, 0x10}, + {0x37e1, 0x10}, + {0x37e2, 0x18}, + {0x37e3, 0x08}, + {0x37e4, 0x08}, + {0x37e5, 0x02}, + {0x37e6, 0x08}, + + /* 1928x1092 */ + {0x3800, 0x00}, + {0x3801, 0x00}, + {0x3802, 0x00}, + {0x3803, 0x00}, + {0x3804, 0x07}, + {0x3805, 0x8f}, + {0x3806, 0x04}, + {0x3807, 0x47}, + {0x3808, 0x07}, + {0x3809, 0x88}, + {0x380a, 0x04}, + {0x380b, 0x44}, + {0x380c, 0x04}, + {0x380d, 0x74}, + {0x380e, 0x09}, + {0x380f, 0x18}, + {0x3810, 0x00}, + {0x3811, 0x02}, + {0x3812, 0x00}, + {0x3813, 0x02}, + {0x3814, 0x01}, + {0x3815, 0x01}, + {0x3816, 0x01}, + {0x3817, 0x01}, + + {0x3820, 0xb0}, + {0x3821, 0x00}, + {0x3822, 0x80}, + {0x3823, 0x08}, + {0x3824, 0x00}, + {0x3825, 0x20}, + {0x3826, 0x00}, + {0x3827, 0x08}, + {0x382a, 0x00}, + {0x382b, 0x08}, + {0x382d, 0x00}, + {0x382e, 0x00}, + {0x382f, 0x23}, + {0x3834, 0x00}, + {0x3839, 0x00}, + {0x383a, 0xd1}, + {0x383e, 0x03}, + {0x393d, 0x29}, + {0x393f, 0x6e}, + {0x394b, 0x06}, + {0x394c, 0x06}, + {0x394d, 0x08}, + {0x394e, 0x0a}, + {0x394f, 0x01}, + {0x3950, 0x01}, + {0x3951, 0x01}, + {0x3952, 0x01}, + {0x3953, 0x01}, + {0x3954, 0x01}, + {0x3955, 0x01}, + {0x3956, 0x01}, + {0x3957, 0x0e}, + {0x3958, 0x08}, + {0x3959, 0x08}, + {0x395a, 0x08}, + {0x395b, 0x13}, + {0x395c, 0x09}, + {0x395d, 0x05}, + {0x395e, 0x02}, + {0x395f, 0x00}, + {0x395f, 0x00}, + {0x3960, 0x00}, + {0x3961, 0x00}, + {0x3962, 0x00}, + {0x3963, 0x00}, + {0x3964, 0x00}, + {0x3965, 0x00}, + {0x3966, 0x00}, + {0x3967, 0x00}, + {0x3968, 0x01}, + {0x3969, 0x01}, + {0x396a, 0x01}, + {0x396b, 0x01}, + {0x396c, 0x10}, + {0x396d, 0xf0}, + {0x396e, 0x11}, + {0x396f, 0x00}, + {0x3970, 0x37}, + {0x3971, 0x37}, + {0x3972, 0x37}, + {0x3973, 0x37}, + {0x3974, 0x00}, + {0x3975, 0x3c}, + {0x3976, 0x3c}, + {0x3977, 0x3c}, + {0x3978, 0x3c}, + {0x3c00, 0x0f}, + {0x3c20, 0x01}, + {0x3c21, 0x08}, + {0x3f00, 0x8b}, + {0x3f02, 0x0f}, + {0x4000, 0xc3}, + {0x4001, 0xe0}, + {0x4002, 0x00}, + {0x4003, 0x40}, + {0x4008, 0x04}, + {0x4009, 0x23}, + {0x400a, 0x04}, + {0x400b, 0x01}, + {0x4041, 0x20}, + {0x4077, 0x06}, + {0x4078, 0x00}, + {0x4079, 0x1a}, + {0x407a, 0x7f}, + {0x407b, 0x01}, + {0x4080, 0x03}, + {0x4081, 0x84}, + {0x4308, 0x03}, + {0x4309, 0xff}, + {0x430d, 0x00}, + {0x4806, 0x00}, + {0x4813, 0x00}, + {0x4837, 0x10}, + {0x4857, 0x05}, + {0x4884, 0x04}, + {0x4500, 0x07}, + {0x4501, 0x00}, + {0x4503, 0x00}, + {0x450a, 0x04}, + {0x450e, 0x00}, + {0x450f, 0x00}, + {0x4800, 0x64}, + {0x4900, 0x00}, + {0x4901, 0x00}, + {0x4902, 0x01}, + {0x4d00, 0x03}, + {0x4d01, 0xd8}, + {0x4d02, 0xba}, + {0x4d03, 0xa0}, + {0x4d04, 0xb7}, + {0x4d05, 0x34}, + {0x4d0d, 0x00}, + {0x5000, 0xfd}, + {0x5001, 0x50}, + {0x5006, 0x00}, + {0x5080, 0x40}, + {0x5181, 0x2b}, + {0x5202, 0xa3}, + {0x5206, 0x01}, + {0x5207, 0x00}, + {0x520a, 0x01}, + {0x520b, 0x00}, + {0x365d, 0x00}, + {0x4815, 0x40}, + {0x4816, 0x12}, + {0x481f, 0x30}, + {0x4f00, 0x01}, + /* plls */ + {0x0303, 0x05}, + {0x0305, 0x90}, + {0x0316, 0x90}, + {0x3016, 0x32}, +}; + +static const char * const ov02c10_test_pattern_menu[] = { + "Disabled", + "Color Bar", + "Top-Bottom Darker Color Bar", + "Right-Left Darker Color Bar", + "Color Bar type 4", +}; + +static const s64 link_freq_menu_items[] = { + OV02C10_LINK_FREQ_400MHZ, +}; + +static const struct ov02c10_mode supported_modes[] = { + { + .width = 1928, + .height = 1092, + .hts = 2280, + .vts_def = 1164, + .vts_min = 1164, + .mipi_lanes = 1, + .reg_sequence = sensor_1928x1092_1lane_30fps_setting, + .sequence_length = ARRAY_SIZE(sensor_1928x1092_1lane_30fps_setting), + }, + { + .width = 1928, + .height = 1092, + .hts = 1140, + .vts_def = 2328, + .vts_min = 2328, + .mipi_lanes = 2, + .reg_sequence = sensor_1928x1092_2lane_30fps_setting, + .sequence_length = ARRAY_SIZE(sensor_1928x1092_2lane_30fps_setting), + }, +}; + +struct ov02c10 { + struct v4l2_subdev sd; + struct media_pad pad; + struct v4l2_ctrl_handler ctrl_handler; + struct regmap *regmap; + + /* V4L2 Controls */ + struct v4l2_ctrl *link_freq; + struct v4l2_ctrl *pixel_rate; + struct v4l2_ctrl *vblank; + struct v4l2_ctrl *hblank; + struct v4l2_ctrl *exposure; + + struct clk *img_clk; + struct regulator *avdd; + struct gpio_desc *reset; + struct gpio_desc *handshake; + + /* Current mode */ + const struct ov02c10_mode *cur_mode; + + /* To serialize asynchronous callbacks */ + struct mutex mutex; + + /* MIPI lanes used */ + u8 mipi_lanes; + + /* Streaming on/off */ + bool streaming; +}; + +static inline struct ov02c10 *to_ov02c10(struct v4l2_subdev *subdev) +{ + return container_of(subdev, struct ov02c10, sd); +} + +static int ov02c10_test_pattern(struct ov02c10 *ov02c10, int pattern) +{ + int ret = 0; + + if (!pattern) + return cci_update_bits(ov02c10->regmap, OV02C10_REG_TEST_PATTERN, + BIT(7), 0, NULL); + + cci_update_bits(ov02c10->regmap, OV02C10_REG_TEST_PATTERN, + 0x03, pattern - 1, &ret); + if (ret) + return ret; + + cci_update_bits(ov02c10->regmap, OV02C10_REG_TEST_PATTERN, + BIT(7), OV02C10_TEST_PATTERN_ENABLE, &ret); + + return ret; +} + +static int ov02c10_set_ctrl(struct v4l2_ctrl *ctrl) +{ + struct ov02c10 *ov02c10 = container_of(ctrl->handler, + struct ov02c10, ctrl_handler); + struct i2c_client *client = v4l2_get_subdevdata(&ov02c10->sd); + s64 exposure_max; + int ret = 0; + + /* Propagate change of current control to all related controls */ + if (ctrl->id == V4L2_CID_VBLANK) { + /* Update max exposure while meeting expected vblanking */ + exposure_max = ov02c10->cur_mode->height + ctrl->val - + OV02C10_EXPOSURE_MAX_MARGIN; + __v4l2_ctrl_modify_range(ov02c10->exposure, + ov02c10->exposure->minimum, + exposure_max, ov02c10->exposure->step, + exposure_max); + } + + /* V4L2 controls values will be applied only when power is already up */ + if (!pm_runtime_get_if_in_use(&client->dev)) + return 0; + + switch (ctrl->id) { + case V4L2_CID_ANALOGUE_GAIN: + cci_write(ov02c10->regmap, OV02C10_REG_ANALOG_GAIN, + ctrl->val << 4, &ret); + break; + + case V4L2_CID_DIGITAL_GAIN: + cci_write(ov02c10->regmap, OV02C10_REG_DIGITAL_GAIN, + ctrl->val << 6, &ret); + break; + + case V4L2_CID_EXPOSURE: + cci_write(ov02c10->regmap, OV02C10_REG_EXPOSURE, + ctrl->val, &ret); + break; + + case V4L2_CID_VBLANK: + cci_write(ov02c10->regmap, OV02C10_REG_VTS, + ov02c10->cur_mode->height + ctrl->val, &ret); + break; + + case V4L2_CID_TEST_PATTERN: + ret = ov02c10_test_pattern(ov02c10, ctrl->val); + break; + + default: + ret = -EINVAL; + break; + } + + pm_runtime_put(&client->dev); + + return ret; +} + +static const struct v4l2_ctrl_ops ov02c10_ctrl_ops = { + .s_ctrl = ov02c10_set_ctrl, +}; + +static int ov02c10_init_controls(struct ov02c10 *ov02c10) +{ + struct v4l2_ctrl_handler *ctrl_hdlr; + const struct ov02c10_mode *cur_mode; + s64 exposure_max, h_blank; + u32 vblank_min, vblank_max, vblank_default; + int size; + int ret = 0; + + ctrl_hdlr = &ov02c10->ctrl_handler; + ret = v4l2_ctrl_handler_init(ctrl_hdlr, 8); + if (ret) + return ret; + + ctrl_hdlr->lock = &ov02c10->mutex; + cur_mode = ov02c10->cur_mode; + size = ARRAY_SIZE(link_freq_menu_items); + + ov02c10->link_freq = v4l2_ctrl_new_int_menu(ctrl_hdlr, + &ov02c10_ctrl_ops, + V4L2_CID_LINK_FREQ, + size - 1, 0, + link_freq_menu_items); + if (ov02c10->link_freq) + ov02c10->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY; + + ov02c10->pixel_rate = v4l2_ctrl_new_std(ctrl_hdlr, &ov02c10_ctrl_ops, + V4L2_CID_PIXEL_RATE, 0, + OV02C10_SCLK, 1, OV02C10_SCLK); + + vblank_min = cur_mode->vts_min - cur_mode->height; + vblank_max = OV02C10_VTS_MAX - cur_mode->height; + vblank_default = cur_mode->vts_def - cur_mode->height; + ov02c10->vblank = v4l2_ctrl_new_std(ctrl_hdlr, &ov02c10_ctrl_ops, + V4L2_CID_VBLANK, vblank_min, + vblank_max, 1, vblank_default); + + h_blank = cur_mode->hts - cur_mode->width; + ov02c10->hblank = v4l2_ctrl_new_std(ctrl_hdlr, &ov02c10_ctrl_ops, + V4L2_CID_HBLANK, h_blank, h_blank, + 1, h_blank); + if (ov02c10->hblank) + ov02c10->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY; + + v4l2_ctrl_new_std(ctrl_hdlr, &ov02c10_ctrl_ops, V4L2_CID_ANALOGUE_GAIN, + OV02C10_ANAL_GAIN_MIN, OV02C10_ANAL_GAIN_MAX, + OV02C10_ANAL_GAIN_STEP, OV02C10_ANAL_GAIN_DEFAULT); + v4l2_ctrl_new_std(ctrl_hdlr, &ov02c10_ctrl_ops, V4L2_CID_DIGITAL_GAIN, + OV02C10_DGTL_GAIN_MIN, OV02C10_DGTL_GAIN_MAX, + OV02C10_DGTL_GAIN_STEP, OV02C10_DGTL_GAIN_DEFAULT); + exposure_max = cur_mode->vts_def - OV02C10_EXPOSURE_MAX_MARGIN; + ov02c10->exposure = v4l2_ctrl_new_std(ctrl_hdlr, &ov02c10_ctrl_ops, + V4L2_CID_EXPOSURE, + OV02C10_EXPOSURE_MIN, + exposure_max, + OV02C10_EXPOSURE_STEP, + exposure_max); + v4l2_ctrl_new_std_menu_items(ctrl_hdlr, &ov02c10_ctrl_ops, + V4L2_CID_TEST_PATTERN, + ARRAY_SIZE(ov02c10_test_pattern_menu) - 1, + 0, 0, ov02c10_test_pattern_menu); + if (ctrl_hdlr->error) + return ctrl_hdlr->error; + + ov02c10->sd.ctrl_handler = ctrl_hdlr; + + return 0; +} + +static void ov02c10_update_pad_format(const struct ov02c10_mode *mode, + struct v4l2_mbus_framefmt *fmt) +{ + fmt->width = mode->width; + fmt->height = mode->height; + fmt->code = MEDIA_BUS_FMT_SGRBG10_1X10; + fmt->field = V4L2_FIELD_NONE; +} + +static int ov02c10_start_streaming(struct ov02c10 *ov02c10) +{ + struct i2c_client *client = v4l2_get_subdevdata(&ov02c10->sd); + const struct reg_sequence *reg_sequence; + int sequence_length; + int ret = 0; + + reg_sequence = ov02c10->cur_mode->reg_sequence; + sequence_length = ov02c10->cur_mode->sequence_length; + ret = regmap_multi_reg_write(ov02c10->regmap, + reg_sequence, sequence_length); + if (ret) { + dev_err(&client->dev, "failed to set mode"); + return ret; + } + + ret = __v4l2_ctrl_handler_setup(ov02c10->sd.ctrl_handler); + if (ret) + return ret; + + ret = cci_write(ov02c10->regmap, OV02C10_REG_STREAM_CONTROL, 1, NULL); + if (ret) + dev_err(&client->dev, "failed to start streaming"); + + return ret; +} + +static void ov02c10_stop_streaming(struct ov02c10 *ov02c10) +{ + struct i2c_client *client = v4l2_get_subdevdata(&ov02c10->sd); + int ret = 0; + + ret = cci_write(ov02c10->regmap, OV02C10_REG_STREAM_CONTROL, 0, NULL); + if (ret) + dev_err(&client->dev, "failed to stop streaming"); +} + +static int ov02c10_set_stream(struct v4l2_subdev *sd, int enable) +{ + struct ov02c10 *ov02c10 = to_ov02c10(sd); + struct i2c_client *client = v4l2_get_subdevdata(sd); + int ret = 0; + + if (ov02c10->streaming == enable) + return 0; + + mutex_lock(&ov02c10->mutex); + if (enable) { + ret = pm_runtime_get_sync(&client->dev); + if (ret < 0) { + pm_runtime_put_noidle(&client->dev); + mutex_unlock(&ov02c10->mutex); + return ret; + } + + ret = ov02c10_start_streaming(ov02c10); + if (ret) { + enable = 0; + ov02c10_stop_streaming(ov02c10); + pm_runtime_put(&client->dev); + } + } else { + ov02c10_stop_streaming(ov02c10); + pm_runtime_put(&client->dev); + } + + ov02c10->streaming = enable; + mutex_unlock(&ov02c10->mutex); + + return ret; +} + +/* This function tries to get power control resources */ +static int ov02c10_get_pm_resources(struct device *dev) +{ + struct v4l2_subdev *sd = dev_get_drvdata(dev); + struct ov02c10 *ov02c10 = to_ov02c10(sd); + int ret; + + ov02c10->reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW); + if (IS_ERR(ov02c10->reset)) + return dev_err_probe(dev, PTR_ERR(ov02c10->reset), + "failed to get reset gpio\n"); + + ov02c10->handshake = devm_gpiod_get_optional(dev, "handshake", + GPIOD_OUT_LOW); + if (IS_ERR(ov02c10->handshake)) + return dev_err_probe(dev, PTR_ERR(ov02c10->handshake), + "failed to get handshake gpio\n"); + + ov02c10->img_clk = devm_clk_get_optional(dev, NULL); + if (IS_ERR(ov02c10->img_clk)) + return dev_err_probe(dev, PTR_ERR(ov02c10->img_clk), + "failed to get imaging clock\n"); + + ov02c10->avdd = devm_regulator_get_optional(dev, "avdd"); + if (IS_ERR(ov02c10->avdd)) { + ret = PTR_ERR(ov02c10->avdd); + ov02c10->avdd = NULL; + if (ret != -ENODEV) + return dev_err_probe(dev, ret, + "failed to get avdd regulator\n"); + } + + return 0; +} + +static int ov02c10_power_off(struct device *dev) +{ + struct v4l2_subdev *sd = dev_get_drvdata(dev); + struct ov02c10 *ov02c10 = to_ov02c10(sd); + int ret = 0; + + gpiod_set_value_cansleep(ov02c10->reset, 1); + gpiod_set_value_cansleep(ov02c10->handshake, 0); + + if (ov02c10->avdd) + ret = regulator_disable(ov02c10->avdd); + + clk_disable_unprepare(ov02c10->img_clk); + + return ret; +} + +static int ov02c10_power_on(struct device *dev) +{ + struct v4l2_subdev *sd = dev_get_drvdata(dev); + struct ov02c10 *ov02c10 = to_ov02c10(sd); + int ret; + + ret = clk_prepare_enable(ov02c10->img_clk); + if (ret < 0) { + dev_err(dev, "failed to enable imaging clock: %d", ret); + return ret; + } + + if (ov02c10->avdd) { + ret = regulator_enable(ov02c10->avdd); + if (ret < 0) { + dev_err(dev, "failed to enable avdd: %d", ret); + clk_disable_unprepare(ov02c10->img_clk); + return ret; + } + } + gpiod_set_value_cansleep(ov02c10->handshake, 1); + gpiod_set_value_cansleep(ov02c10->reset, 0); + + /* Lattice MIPI aggregator with some version FW needs longer delay + * after handshake triggered. We set 25ms as a safe value and wait + * for a stable version FW. + */ + msleep_interruptible(25); + + return ret; +} + +static int __maybe_unused ov02c10_suspend(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct v4l2_subdev *sd = i2c_get_clientdata(client); + struct ov02c10 *ov02c10 = to_ov02c10(sd); + + mutex_lock(&ov02c10->mutex); + if (ov02c10->streaming) + ov02c10_stop_streaming(ov02c10); + + mutex_unlock(&ov02c10->mutex); + + return 0; +} + +static int __maybe_unused ov02c10_resume(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct v4l2_subdev *sd = i2c_get_clientdata(client); + struct ov02c10 *ov02c10 = to_ov02c10(sd); + int ret = 0; + + mutex_lock(&ov02c10->mutex); + if (!ov02c10->streaming) + goto exit; + + ret = ov02c10_start_streaming(ov02c10); + if (ret) { + ov02c10->streaming = false; + ov02c10_stop_streaming(ov02c10); + } + +exit: + mutex_unlock(&ov02c10->mutex); + return ret; +} + +static int ov02c10_set_format(struct v4l2_subdev *sd, + struct v4l2_subdev_state *sd_state, + struct v4l2_subdev_format *fmt) +{ + struct ov02c10 *ov02c10 = to_ov02c10(sd); + const struct ov02c10_mode *mode; + s32 vblank_def, h_blank; + + if (ov02c10->mipi_lanes == 1) + mode = &supported_modes[0]; + else + mode = &supported_modes[1]; + + mutex_lock(&ov02c10->mutex); + ov02c10_update_pad_format(mode, &fmt->format); + if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { + *v4l2_subdev_state_get_format(sd_state, fmt->pad) = fmt->format; + } else { + ov02c10->cur_mode = mode; + __v4l2_ctrl_s_ctrl(ov02c10->link_freq, mode->link_freq_index); + __v4l2_ctrl_s_ctrl_int64(ov02c10->pixel_rate, OV02C10_SCLK); + + /* Update limits and set FPS to default */ + vblank_def = mode->vts_def - mode->height; + __v4l2_ctrl_modify_range(ov02c10->vblank, + mode->vts_min - mode->height, + OV02C10_VTS_MAX - mode->height, 1, + vblank_def); + __v4l2_ctrl_s_ctrl(ov02c10->vblank, vblank_def); + h_blank = mode->hts - mode->width; + __v4l2_ctrl_modify_range(ov02c10->hblank, h_blank, h_blank, 1, + h_blank); + } + mutex_unlock(&ov02c10->mutex); + + return 0; +} + +static int ov02c10_get_format(struct v4l2_subdev *sd, + struct v4l2_subdev_state *sd_state, + struct v4l2_subdev_format *fmt) +{ + struct ov02c10 *ov02c10 = to_ov02c10(sd); + + mutex_lock(&ov02c10->mutex); + if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) + fmt->format = *v4l2_subdev_state_get_format(sd_state, fmt->pad); + else + ov02c10_update_pad_format(ov02c10->cur_mode, &fmt->format); + + mutex_unlock(&ov02c10->mutex); + + return 0; +} + +static int ov02c10_enum_mbus_code(struct v4l2_subdev *sd, + struct v4l2_subdev_state *sd_state, + struct v4l2_subdev_mbus_code_enum *code) +{ + if (code->index > 0) + return -EINVAL; + + code->code = MEDIA_BUS_FMT_SGRBG10_1X10; + + return 0; +} + +static int ov02c10_enum_frame_size(struct v4l2_subdev *sd, + struct v4l2_subdev_state *sd_state, + struct v4l2_subdev_frame_size_enum *fse) +{ + if (fse->index >= ARRAY_SIZE(supported_modes)) + return -EINVAL; + + if (fse->code != MEDIA_BUS_FMT_SGRBG10_1X10) + return -EINVAL; + + fse->min_width = supported_modes[fse->index].width; + fse->max_width = fse->min_width; + fse->min_height = supported_modes[fse->index].height; + fse->max_height = fse->min_height; + + return 0; +} + +static int ov02c10_init_state(struct v4l2_subdev *sd, + struct v4l2_subdev_state *sd_state) +{ + ov02c10_update_pad_format(&supported_modes[0], + v4l2_subdev_state_get_format(sd_state, 0)); + + return 0; +} + +static const struct v4l2_subdev_video_ops ov02c10_video_ops = { + .s_stream = ov02c10_set_stream, +}; + +static const struct v4l2_subdev_pad_ops ov02c10_pad_ops = { + .set_fmt = ov02c10_set_format, + .get_fmt = ov02c10_get_format, + .enum_mbus_code = ov02c10_enum_mbus_code, + .enum_frame_size = ov02c10_enum_frame_size, +}; + +static const struct v4l2_subdev_ops ov02c10_subdev_ops = { + .video = &ov02c10_video_ops, + .pad = &ov02c10_pad_ops, +}; + +static const struct media_entity_operations ov02c10_subdev_entity_ops = { + .link_validate = v4l2_subdev_link_validate, +}; + +static const struct v4l2_subdev_internal_ops ov02c10_internal_ops = { + .init_state = ov02c10_init_state, +}; + +static int ov02c10_identify_module(struct ov02c10 *ov02c10) +{ + struct i2c_client *client = v4l2_get_subdevdata(&ov02c10->sd); + u64 chip_id; + u32 ret = 0; + + ov02c10->regmap = devm_cci_regmap_init_i2c(client, 16); + cci_read(ov02c10->regmap, OV02C10_REG_CHIP_ID, &chip_id, &ret); + if (ret) + return ret; + + if (chip_id != OV02C10_CHIP_ID) { + dev_err(&client->dev, "chip id mismatch: %x!=%llx", + OV02C10_CHIP_ID, chip_id); + return -ENXIO; + } + + return 0; +} + +static int ov02c10_check_hwcfg(struct device *dev, struct ov02c10 *ov02c10) +{ + struct v4l2_fwnode_endpoint bus_cfg = { + .bus_type = V4L2_MBUS_CSI2_DPHY + }; + struct fwnode_handle *ep; + struct fwnode_handle *fwnode = dev_fwnode(dev); + unsigned int i, j; + int ret; + u32 ext_clk; + + if (!fwnode) + return -ENXIO; + + ep = fwnode_graph_get_next_endpoint(fwnode, NULL); + if (!ep) + return -EPROBE_DEFER; + + ret = fwnode_property_read_u32(dev_fwnode(dev), "clock-frequency", + &ext_clk); + if (ret) { + dev_err(dev, "can't get clock frequency"); + return ret; + } + + ret = v4l2_fwnode_endpoint_alloc_parse(ep, &bus_cfg); + fwnode_handle_put(ep); + if (ret) + return ret; + + if (!bus_cfg.nr_of_link_frequencies) { + dev_err(dev, "no link frequencies defined"); + ret = -EINVAL; + goto out_err; + } + + for (i = 0; i < ARRAY_SIZE(link_freq_menu_items); i++) { + for (j = 0; j < bus_cfg.nr_of_link_frequencies; j++) { + if (link_freq_menu_items[i] == + bus_cfg.link_frequencies[j]) + break; + } + + if (j == bus_cfg.nr_of_link_frequencies) { + dev_err(dev, "no link frequency %lld supported", + link_freq_menu_items[i]); + ret = -EINVAL; + goto out_err; + } + } + + if (bus_cfg.bus.mipi_csi2.num_data_lanes != 2 && + bus_cfg.bus.mipi_csi2.num_data_lanes != 4) { + dev_err(dev, "number of CSI2 data lanes %d is not supported", + bus_cfg.bus.mipi_csi2.num_data_lanes); + return(-EINVAL); + } + ov02c10->mipi_lanes = bus_cfg.bus.mipi_csi2.num_data_lanes; + +out_err: + v4l2_fwnode_endpoint_free(&bus_cfg); + + return ret; +} + +static void ov02c10_remove(struct i2c_client *client) +{ + struct v4l2_subdev *sd = i2c_get_clientdata(client); + struct ov02c10 *ov02c10 = to_ov02c10(sd); + + v4l2_async_unregister_subdev(sd); + media_entity_cleanup(&sd->entity); + v4l2_ctrl_handler_free(sd->ctrl_handler); + pm_runtime_disable(&client->dev); + mutex_destroy(&ov02c10->mutex); +} + +static int ov02c10_probe(struct i2c_client *client) +{ + struct ov02c10 *ov02c10; + int ret = 0; + + ov02c10 = devm_kzalloc(&client->dev, sizeof(*ov02c10), GFP_KERNEL); + if (!ov02c10) + return -ENOMEM; + + /* Check HW config */ + ret = ov02c10_check_hwcfg(&client->dev, ov02c10); + if (ret) { + dev_err(&client->dev, "failed to check hwcfg: %d", ret); + return ret; + } + + v4l2_i2c_subdev_init(&ov02c10->sd, client, &ov02c10_subdev_ops); + ov02c10_get_pm_resources(&client->dev); + + ret = ov02c10_power_on(&client->dev); + if (ret) { + dev_err_probe(&client->dev, ret, "failed to power on\n"); + return ret; + } + + ret = ov02c10_identify_module(ov02c10); + if (ret) { + dev_err(&client->dev, "failed to find sensor: %d", ret); + goto probe_error_ret; + } + + mutex_init(&ov02c10->mutex); + ov02c10->cur_mode = &supported_modes[0]; + if (ov02c10->mipi_lanes == 2) + ov02c10->cur_mode = &supported_modes[1]; + ret = ov02c10_init_controls(ov02c10); + if (ret) { + dev_err(&client->dev, "failed to init controls: %d", ret); + goto probe_error_v4l2_ctrl_handler_free; + } + + ov02c10->sd.internal_ops = &ov02c10_internal_ops; + ov02c10->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; + ov02c10->sd.entity.ops = &ov02c10_subdev_entity_ops; + ov02c10->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR; + ov02c10->pad.flags = MEDIA_PAD_FL_SOURCE; + ret = media_entity_pads_init(&ov02c10->sd.entity, 1, &ov02c10->pad); + if (ret) { + dev_err(&client->dev, "failed to init entity pads: %d", ret); + goto probe_error_v4l2_ctrl_handler_free; + } + + ret = v4l2_async_register_subdev_sensor(&ov02c10->sd); + if (ret < 0) { + dev_err(&client->dev, "failed to register V4L2 subdev: %d", + ret); + goto probe_error_media_entity_cleanup; + } + + /* + * Device is already turned on by i2c-core with ACPI domain PM. + * Enable runtime PM and turn off the device. + */ + pm_runtime_set_active(&client->dev); + pm_runtime_enable(&client->dev); + pm_runtime_idle(&client->dev); + + return 0; + +probe_error_media_entity_cleanup: + media_entity_cleanup(&ov02c10->sd.entity); + +probe_error_v4l2_ctrl_handler_free: + v4l2_ctrl_handler_free(ov02c10->sd.ctrl_handler); + mutex_destroy(&ov02c10->mutex); + +probe_error_ret: + ov02c10_power_off(&client->dev); + + return ret; +} + +static const struct dev_pm_ops ov02c10_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(ov02c10_suspend, ov02c10_resume) + SET_RUNTIME_PM_OPS(ov02c10_power_off, ov02c10_power_on, NULL) +}; + +#ifdef CONFIG_ACPI +static const struct acpi_device_id ov02c10_acpi_ids[] = { + {"OVTI02C1"}, + {} +}; + +MODULE_DEVICE_TABLE(acpi, ov02c10_acpi_ids); +#endif + +static struct i2c_driver ov02c10_i2c_driver = { + .driver = { + .name = "ov02c10", + .pm = &ov02c10_pm_ops, + .acpi_match_table = ACPI_PTR(ov02c10_acpi_ids), + }, + .probe = ov02c10_probe, + .remove = ov02c10_remove, +}; + +module_i2c_driver(ov02c10_i2c_driver); + +MODULE_AUTHOR("Hao Yao "); +MODULE_DESCRIPTION("OmniVision OV02C10 sensor driver"); +MODULE_LICENSE("GPL"); From patchwork Thu Mar 13 18:43:02 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hans de Goede X-Patchwork-Id: 14015788 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 59FB21EE7B1 for ; Thu, 13 Mar 2025 18:43:33 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741891415; cv=none; b=Vr1weTqZrukN2WU+LrU37+gdV09zW/Q2oN71YQytN46cNxnUlWK2kiJIlWhbYiWRq0frlNypU25wnnTESMZ9U+F2AWf4ld4VeEArRBxo1Nbs8o3qCG/dThfGdTCsZqlwmiS9VKl7KN1E4IedDLmMWQ4HKGO0bbSNZyLkbdRTOeo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741891415; c=relaxed/simple; bh=nPI5LnJTaaOlW3Hi17cJkxi2pJiSlTDDnBvuBh98Gnc=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=lpTWLCU10zlzNjAfdS2tVBZsz8xeoV/5sHmV+fJXhL51E7OQrG0AWIvM6HI7A//J+4ekUcK8Jxao1Ij+tMaNLf9aNdYIuSY1eY3OtPLFA0WClX1D0shbe8t3kF01a7svCZTQJNlUMd95C+gZDUp4lfLSRK3A9ZnejGd+gTWmDp4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=AkHfsy2k; arc=none smtp.client-ip=170.10.133.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="AkHfsy2k" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1741891412; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=XjZTVrzFNhXKswbVEu0W+WdDn/XUGAJhoMEJalg+Kr0=; b=AkHfsy2kDgJnPih+5/PIfUAsKESgttO975lHWPRlEbt8YjFFLzngUg29WCCiVpU+tw4Zus fdaKN3z9/JRrFS7Kuvxed5zb6fEOIVfXA3kOkLvsG4mrlOeP6CHndwT1jivx+YuA64iFeB 5XaDT3GeYggbGLmDJUaca6xM9G5uRUA= Received: from mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-58-VLcbs-9jODilJtfO8q8c3Q-1; Thu, 13 Mar 2025 14:43:28 -0400 X-MC-Unique: VLcbs-9jODilJtfO8q8c3Q-1 X-Mimecast-MFC-AGG-ID: VLcbs-9jODilJtfO8q8c3Q_1741891407 Received: from mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.4]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id C38681809CA5; Thu, 13 Mar 2025 18:43:26 +0000 (UTC) Received: from shalem.redhat.com (unknown [10.45.224.5]) by mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 82894300376F; Thu, 13 Mar 2025 18:43:23 +0000 (UTC) From: Hans de Goede To: Sakari Ailus , Heimir Thor Sverrisson Cc: Hans de Goede , Stanislaw Gruszka , Ingvar Hagelund , Joachim Reichel , Bryan O'Donoghue , Hao Yao , Mauro Carvalho Chehab , linux-media@vger.kernel.org Subject: [PATCH v8 02/14] media: ov02c10: merge shared register settings into a shared reg_sequence array Date: Thu, 13 Mar 2025 19:43:02 +0100 Message-ID: <20250313184314.91410-3-hdegoede@redhat.com> In-Reply-To: <20250313184314.91410-1-hdegoede@redhat.com> References: <20250313184314.91410-1-hdegoede@redhat.com> Precedence: bulk X-Mailing-List: linux-media@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.4 Merge shared register settings into a shared reg_sequence array. Signed-off-by: Hans de Goede --- drivers/media/i2c/ov02c10.c | 256 +++++------------------------------- 1 file changed, 34 insertions(+), 222 deletions(-) diff --git a/drivers/media/i2c/ov02c10.c b/drivers/media/i2c/ov02c10.c index 291da9ee1788..f18b48fe8c0d 100644 --- a/drivers/media/i2c/ov02c10.c +++ b/drivers/media/i2c/ov02c10.c @@ -85,20 +85,21 @@ struct ov02c10_mode { /* Sensor register settings for this resolution */ const struct reg_sequence *reg_sequence; const int sequence_length; + /* Sensor register settings for 1 or 2 lane config */ + const struct reg_sequence *lane_settings; + const int lane_settings_length; }; -static const struct reg_sequence sensor_1928x1092_1lane_30fps_setting[] = { +static const struct reg_sequence sensor_1928x1092_30fps_setting[] = { {0x0301, 0x08}, {0x0303, 0x06}, {0x0304, 0x01}, {0x0305, 0xe0}, {0x0313, 0x40}, {0x031c, 0x4f}, - {0x301b, 0xd2}, {0x3020, 0x97}, {0x3022, 0x01}, {0x3026, 0xb4}, - {0x3027, 0xe1}, {0x303b, 0x00}, {0x303c, 0x4f}, {0x303d, 0xe6}, @@ -174,10 +175,6 @@ static const struct reg_sequence sensor_1928x1092_1lane_30fps_setting[] = { {0x3809, 0x88}, {0x380a, 0x04}, {0x380b, 0x44}, - {0x380c, 0x08}, - {0x380d, 0xe8}, - {0x380e, 0x04}, - {0x380f, 0x8c}, {0x3810, 0x00}, {0x3811, 0x02}, {0x3812, 0x00}, @@ -209,7 +206,6 @@ static const struct reg_sequence sensor_1928x1092_1lane_30fps_setting[] = { {0x394b, 0x06}, {0x394c, 0x06}, {0x394d, 0x08}, - {0x394e, 0x0b}, {0x394f, 0x01}, {0x3950, 0x01}, {0x3951, 0x01}, @@ -286,11 +282,9 @@ static const struct reg_sequence sensor_1928x1092_1lane_30fps_setting[] = { {0x450a, 0x04}, {0x450e, 0x00}, {0x450f, 0x00}, - {0x4800, 0x24}, {0x4900, 0x00}, {0x4901, 0x00}, {0x4902, 0x01}, - {0x5000, 0xf5}, {0x5001, 0x50}, {0x5006, 0x00}, {0x5080, 0x40}, @@ -304,6 +298,18 @@ static const struct reg_sequence sensor_1928x1092_1lane_30fps_setting[] = { {0x4815, 0x40}, {0x4816, 0x12}, {0x4f00, 0x01}, +}; + +static const struct reg_sequence sensor_1928x1092_30fps_1lane_setting[] = { + {0x301b, 0xd2}, + {0x3027, 0xe1}, + {0x380c, 0x08}, + {0x380d, 0xe8}, + {0x380e, 0x04}, + {0x380f, 0x8c}, + {0x394e, 0x0b}, + {0x4800, 0x24}, + {0x5000, 0xf5}, /* plls */ {0x0303, 0x05}, {0x0305, 0x90}, @@ -311,211 +317,17 @@ static const struct reg_sequence sensor_1928x1092_1lane_30fps_setting[] = { {0x3016, 0x12}, }; -static const struct reg_sequence sensor_1928x1092_2lane_30fps_setting[] = { - {0x0301, 0x08}, - {0x0303, 0x06}, - {0x0304, 0x01}, - {0x0305, 0xe0}, - {0x0313, 0x40}, - {0x031c, 0x4f}, +static const struct reg_sequence sensor_1928x1092_30fps_2lane_setting[] = { {0x301b, 0xf0}, - {0x3020, 0x97}, - {0x3022, 0x01}, - {0x3026, 0xb4}, {0x3027, 0xf1}, - {0x303b, 0x00}, - {0x303c, 0x4f}, - {0x303d, 0xe6}, - {0x303e, 0x00}, - {0x303f, 0x03}, - {0x3021, 0x23}, - {0x3501, 0x04}, - {0x3502, 0x6c}, - {0x3504, 0x0c}, - {0x3507, 0x00}, - {0x3508, 0x08}, - {0x3509, 0x00}, - {0x350a, 0x01}, - {0x350b, 0x00}, - {0x350c, 0x41}, - {0x3600, 0x84}, - {0x3603, 0x08}, - {0x3610, 0x57}, - {0x3611, 0x1b}, - {0x3613, 0x78}, - {0x3623, 0x00}, - {0x3632, 0xa0}, - {0x3642, 0xe8}, - {0x364c, 0x70}, - {0x365f, 0x0f}, - {0x3708, 0x30}, - {0x3714, 0x24}, - {0x3725, 0x02}, - {0x3737, 0x08}, - {0x3739, 0x28}, - {0x3749, 0x32}, - {0x374a, 0x32}, - {0x374b, 0x32}, - {0x374c, 0x32}, - {0x374d, 0x81}, - {0x374e, 0x81}, - {0x374f, 0x81}, - {0x3752, 0x36}, - {0x3753, 0x36}, - {0x3754, 0x36}, - {0x3761, 0x00}, - {0x376c, 0x81}, - {0x3774, 0x18}, - {0x3776, 0x08}, - {0x377c, 0x81}, - {0x377d, 0x81}, - {0x377e, 0x81}, - {0x37a0, 0x44}, - {0x37a6, 0x44}, - {0x37aa, 0x0d}, - {0x37ae, 0x00}, - {0x37cb, 0x03}, - {0x37cc, 0x01}, - {0x37d8, 0x02}, - {0x37d9, 0x10}, - {0x37e1, 0x10}, - {0x37e2, 0x18}, - {0x37e3, 0x08}, - {0x37e4, 0x08}, - {0x37e5, 0x02}, - {0x37e6, 0x08}, - - /* 1928x1092 */ - {0x3800, 0x00}, - {0x3801, 0x00}, - {0x3802, 0x00}, - {0x3803, 0x00}, - {0x3804, 0x07}, - {0x3805, 0x8f}, - {0x3806, 0x04}, - {0x3807, 0x47}, - {0x3808, 0x07}, - {0x3809, 0x88}, - {0x380a, 0x04}, - {0x380b, 0x44}, {0x380c, 0x04}, {0x380d, 0x74}, {0x380e, 0x09}, {0x380f, 0x18}, - {0x3810, 0x00}, - {0x3811, 0x02}, - {0x3812, 0x00}, - {0x3813, 0x02}, - {0x3814, 0x01}, - {0x3815, 0x01}, - {0x3816, 0x01}, - {0x3817, 0x01}, - - {0x3820, 0xb0}, - {0x3821, 0x00}, - {0x3822, 0x80}, - {0x3823, 0x08}, - {0x3824, 0x00}, - {0x3825, 0x20}, - {0x3826, 0x00}, - {0x3827, 0x08}, - {0x382a, 0x00}, - {0x382b, 0x08}, - {0x382d, 0x00}, - {0x382e, 0x00}, - {0x382f, 0x23}, - {0x3834, 0x00}, - {0x3839, 0x00}, - {0x383a, 0xd1}, - {0x383e, 0x03}, - {0x393d, 0x29}, - {0x393f, 0x6e}, - {0x394b, 0x06}, - {0x394c, 0x06}, - {0x394d, 0x08}, {0x394e, 0x0a}, - {0x394f, 0x01}, - {0x3950, 0x01}, - {0x3951, 0x01}, - {0x3952, 0x01}, - {0x3953, 0x01}, - {0x3954, 0x01}, - {0x3955, 0x01}, - {0x3956, 0x01}, - {0x3957, 0x0e}, - {0x3958, 0x08}, - {0x3959, 0x08}, - {0x395a, 0x08}, - {0x395b, 0x13}, - {0x395c, 0x09}, - {0x395d, 0x05}, - {0x395e, 0x02}, - {0x395f, 0x00}, - {0x395f, 0x00}, - {0x3960, 0x00}, - {0x3961, 0x00}, - {0x3962, 0x00}, - {0x3963, 0x00}, - {0x3964, 0x00}, - {0x3965, 0x00}, - {0x3966, 0x00}, - {0x3967, 0x00}, - {0x3968, 0x01}, - {0x3969, 0x01}, - {0x396a, 0x01}, - {0x396b, 0x01}, - {0x396c, 0x10}, - {0x396d, 0xf0}, - {0x396e, 0x11}, - {0x396f, 0x00}, - {0x3970, 0x37}, - {0x3971, 0x37}, - {0x3972, 0x37}, - {0x3973, 0x37}, - {0x3974, 0x00}, - {0x3975, 0x3c}, - {0x3976, 0x3c}, - {0x3977, 0x3c}, - {0x3978, 0x3c}, - {0x3c00, 0x0f}, - {0x3c20, 0x01}, - {0x3c21, 0x08}, - {0x3f00, 0x8b}, - {0x3f02, 0x0f}, - {0x4000, 0xc3}, - {0x4001, 0xe0}, - {0x4002, 0x00}, - {0x4003, 0x40}, - {0x4008, 0x04}, - {0x4009, 0x23}, - {0x400a, 0x04}, - {0x400b, 0x01}, {0x4041, 0x20}, - {0x4077, 0x06}, - {0x4078, 0x00}, - {0x4079, 0x1a}, - {0x407a, 0x7f}, - {0x407b, 0x01}, - {0x4080, 0x03}, - {0x4081, 0x84}, - {0x4308, 0x03}, - {0x4309, 0xff}, - {0x430d, 0x00}, - {0x4806, 0x00}, - {0x4813, 0x00}, - {0x4837, 0x10}, - {0x4857, 0x05}, {0x4884, 0x04}, - {0x4500, 0x07}, - {0x4501, 0x00}, - {0x4503, 0x00}, - {0x450a, 0x04}, - {0x450e, 0x00}, - {0x450f, 0x00}, {0x4800, 0x64}, - {0x4900, 0x00}, - {0x4901, 0x00}, - {0x4902, 0x01}, {0x4d00, 0x03}, {0x4d01, 0xd8}, {0x4d02, 0xba}, @@ -524,20 +336,7 @@ static const struct reg_sequence sensor_1928x1092_2lane_30fps_setting[] = { {0x4d05, 0x34}, {0x4d0d, 0x00}, {0x5000, 0xfd}, - {0x5001, 0x50}, - {0x5006, 0x00}, - {0x5080, 0x40}, - {0x5181, 0x2b}, - {0x5202, 0xa3}, - {0x5206, 0x01}, - {0x5207, 0x00}, - {0x520a, 0x01}, - {0x520b, 0x00}, - {0x365d, 0x00}, - {0x4815, 0x40}, - {0x4816, 0x12}, {0x481f, 0x30}, - {0x4f00, 0x01}, /* plls */ {0x0303, 0x05}, {0x0305, 0x90}, @@ -565,8 +364,10 @@ static const struct ov02c10_mode supported_modes[] = { .vts_def = 1164, .vts_min = 1164, .mipi_lanes = 1, - .reg_sequence = sensor_1928x1092_1lane_30fps_setting, - .sequence_length = ARRAY_SIZE(sensor_1928x1092_1lane_30fps_setting), + .reg_sequence = sensor_1928x1092_30fps_setting, + .sequence_length = ARRAY_SIZE(sensor_1928x1092_30fps_setting), + .lane_settings = sensor_1928x1092_30fps_1lane_setting, + .lane_settings_length = ARRAY_SIZE(sensor_1928x1092_30fps_1lane_setting), }, { .width = 1928, @@ -575,8 +376,10 @@ static const struct ov02c10_mode supported_modes[] = { .vts_def = 2328, .vts_min = 2328, .mipi_lanes = 2, - .reg_sequence = sensor_1928x1092_2lane_30fps_setting, - .sequence_length = ARRAY_SIZE(sensor_1928x1092_2lane_30fps_setting), + .reg_sequence = sensor_1928x1092_30fps_setting, + .sequence_length = ARRAY_SIZE(sensor_1928x1092_30fps_setting), + .lane_settings = sensor_1928x1092_30fps_2lane_setting, + .lane_settings_length = ARRAY_SIZE(sensor_1928x1092_30fps_2lane_setting), }, }; @@ -791,6 +594,15 @@ static int ov02c10_start_streaming(struct ov02c10 *ov02c10) return ret; } + reg_sequence = ov02c10->cur_mode->lane_settings; + sequence_length = ov02c10->cur_mode->lane_settings_length; + ret = regmap_multi_reg_write(ov02c10->regmap, + reg_sequence, sequence_length); + if (ret) { + dev_err(&client->dev, "failed to write lane settings\n"); + return ret; + } + ret = __v4l2_ctrl_handler_setup(ov02c10->sd.ctrl_handler); if (ret) return ret; From patchwork Thu Mar 13 18:43:03 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hans de Goede X-Patchwork-Id: 14015789 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C8D4B1EFF85 for ; Thu, 13 Mar 2025 18:43:36 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741891418; cv=none; b=gDxWmPC7LGWajgzfQH6ZCWf5hRqF6U+nzVrBqiJXEUd3Bf1HNAMIrzc65ASjnNALi0cfdt9GW+dXc8riRjxJI3pKsj+TEtpdpfbIbAlj+hgFLFQj0PgQ2IgDG6w65anLqidSGjSE8qF08NtGjgVIIZmOuQqbiwsZPmdp1ACN2IM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741891418; c=relaxed/simple; bh=XD/m5tMq6xOwMinqeDfPt4wgndx5FUgiRdzMqzu/Iow=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=pS+0q5oeH9Jv/VGhKVd/0dFD9HIVkSSv21Sju/mKX8k2KlYuVWVQsgs4UXGk9euLS2Y6MKLh0lAZ41ZSgyods54CywPem3bhc+zEUsEz2THZtRMrhfUEhFBAtoy6gnVmzfK/zoua0x44hvJyYCEFTOI3ICXZf28Qbtu4fGg9QGo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=ZtbjCqxY; arc=none smtp.client-ip=170.10.129.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="ZtbjCqxY" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1741891415; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=lKYOPIxQXXhG7YOxYNtFp2F9bfRNF+MgS5Ll8j219hE=; b=ZtbjCqxYm1whAi77xIVexWw06iGmaz666hrf1uWnDNK0v016jSjufzbaQdMR2tYqJ6ExxX gurGgUgknzylk7poSUAZPIV+dxGitKVcKgUnSpdV2UrWoajAFgZ/Oe9Bl6vase507i61vO YpCM4vkZoY/PO9sf1Dfw123mM+DfU9k= Received: from mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-615-d6eOComiMJGOMYf7LAZo_Q-1; Thu, 13 Mar 2025 14:43:32 -0400 X-MC-Unique: d6eOComiMJGOMYf7LAZo_Q-1 X-Mimecast-MFC-AGG-ID: d6eOComiMJGOMYf7LAZo_Q_1741891410 Received: from mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.4]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 953F61809CA5; Thu, 13 Mar 2025 18:43:30 +0000 (UTC) Received: from shalem.redhat.com (unknown [10.45.224.5]) by mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 3D54C3003770; Thu, 13 Mar 2025 18:43:27 +0000 (UTC) From: Hans de Goede To: Sakari Ailus , Heimir Thor Sverrisson Cc: Hans de Goede , Stanislaw Gruszka , Ingvar Hagelund , Joachim Reichel , Bryan O'Donoghue , Hao Yao , Mauro Carvalho Chehab , linux-media@vger.kernel.org Subject: [PATCH v8 03/14] media: ov02c10: Fix hts for 2 lane mode Date: Thu, 13 Mar 2025 19:43:03 +0100 Message-ID: <20250313184314.91410-4-hdegoede@redhat.com> In-Reply-To: <20250313184314.91410-1-hdegoede@redhat.com> References: <20250313184314.91410-1-hdegoede@redhat.com> Precedence: bulk X-Mailing-List: linux-media@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.4 Using half the hts value when using 2 lanes results in hts < width, which results in reporting a negative hblank value to userspace. The hts value in the mode struct is only used for reporting the hblank control to userspace so this change does not result in any different register settings being written to the sensor. After this change the register-lists are still writing 1140 to the HTS register of the sensor in 2 lane mode, which seems to be a too low value for HTS. But maybe the value of this register is multiplied by 2 internally by the sensor when 2 lanes are used ? Signed-off-by: Hans de Goede --- drivers/media/i2c/ov02c10.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/media/i2c/ov02c10.c b/drivers/media/i2c/ov02c10.c index f18b48fe8c0d..a33f9d4033e6 100644 --- a/drivers/media/i2c/ov02c10.c +++ b/drivers/media/i2c/ov02c10.c @@ -26,6 +26,8 @@ #define OV02C10_REG_STREAM_CONTROL CCI_REG8(0x0100) +#define OV02C10_REG_HTS CCI_REG16(0x380c) + /* vertical-timings from sensor */ #define OV02C10_REG_VTS CCI_REG16(0x380e) #define OV02C10_VTS_MAX 0xffff @@ -372,7 +374,7 @@ static const struct ov02c10_mode supported_modes[] = { { .width = 1928, .height = 1092, - .hts = 1140, + .hts = 2280, .vts_def = 2328, .vts_min = 2328, .mipi_lanes = 2, From patchwork Thu Mar 13 18:43:04 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hans de Goede X-Patchwork-Id: 14015790 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 481761EF393 for ; Thu, 13 Mar 2025 18:43:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741891421; cv=none; b=W95HuBJqrpUZTvt+Rz5uyslvE7CoLLag5X4c3673paoEj3PtQ2Ayb1jXzXC+LoRuw1MC9j0pTl22N1sUa0tkilWA8+ERQbz6RdY8Yu4hjNdL0UeO9eMjR+011OJ02p+J6fS2KYY5SlxnRLWzN5W+NtFPoyeGZEy836EhBNjJAqg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741891421; c=relaxed/simple; bh=rDQH6Olct2STXLluZxjALm7DSsTSzS3lupr+TVZposo=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=N2/kE6xYGqWYHtblfy1cGkT+2kWvykdukwkjlay7E6Ljv0TnF18Cmj7HqVPOlnZ6b68UEiEUd3IxNprJXUDgexcvrfEoNxYCUdSO2Vs0ZNgHqSHcUtebgKfYKFwOmEZlq4KzZ8Jq4rQJ6tSKJ0A53zEmNzr8MPYojODXtb16lwA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=LgMhdSCf; arc=none smtp.client-ip=170.10.133.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="LgMhdSCf" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1741891419; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=1DsfxH7IQFNZirqe6a+FgtK0jMfKRt0KBA+TYAoqc5E=; b=LgMhdSCfYVKt8Wy3KlKB6/CJizsFB/0W1YXojN2bPGog8/2x4phenZ6x0Do7q8RmJF+/GU MYTZyn67fLybEod73/1bghBJJ8FuwqhXP5sOL0X/dV5b8k8rfYzwuQ2UP612NpA9K00fpi iD3KtEBc6W2P7DcKOApXon20oZMG2DY= Received: from mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-392-vBg6U4EFOLmILjnu8VnIjQ-1; Thu, 13 Mar 2025 14:43:35 -0400 X-MC-Unique: vBg6U4EFOLmILjnu8VnIjQ-1 X-Mimecast-MFC-AGG-ID: vBg6U4EFOLmILjnu8VnIjQ_1741891414 Received: from mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.4]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 1AE1E18001E3; Thu, 13 Mar 2025 18:43:34 +0000 (UTC) Received: from shalem.redhat.com (unknown [10.45.224.5]) by mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id EDD35300376F; Thu, 13 Mar 2025 18:43:30 +0000 (UTC) From: Hans de Goede To: Sakari Ailus , Heimir Thor Sverrisson Cc: Hans de Goede , Stanislaw Gruszka , Ingvar Hagelund , Joachim Reichel , Bryan O'Donoghue , Hao Yao , Mauro Carvalho Chehab , linux-media@vger.kernel.org Subject: [PATCH v8 04/14] media: ov02c10: Fix vts_min for 2 lane mode Date: Thu, 13 Mar 2025 19:43:04 +0100 Message-ID: <20250313184314.91410-5-hdegoede@redhat.com> In-Reply-To: <20250313184314.91410-1-hdegoede@redhat.com> References: <20250313184314.91410-1-hdegoede@redhat.com> Precedence: bulk X-Mailing-List: linux-media@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.4 Doubling the default VTS value in 2 lane mode to keep the default fps at 30 fps while doubling the pixelrate make sense. But there is no reason to also double the minimum VTS value. If userspace wants to use the extra bandwidth to get more fps (at the expense of the max exposure time) then this should be allowed. Signed-off-by: Hans de Goede --- drivers/media/i2c/ov02c10.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/i2c/ov02c10.c b/drivers/media/i2c/ov02c10.c index a33f9d4033e6..ad5ab6c8a803 100644 --- a/drivers/media/i2c/ov02c10.c +++ b/drivers/media/i2c/ov02c10.c @@ -376,7 +376,7 @@ static const struct ov02c10_mode supported_modes[] = { .height = 1092, .hts = 2280, .vts_def = 2328, - .vts_min = 2328, + .vts_min = 1164, .mipi_lanes = 2, .reg_sequence = sensor_1928x1092_30fps_setting, .sequence_length = ARRAY_SIZE(sensor_1928x1092_30fps_setting), From patchwork Thu Mar 13 18:43:05 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hans de Goede X-Patchwork-Id: 14015791 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 10E091EFF9D for ; Thu, 13 Mar 2025 18:43:41 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741891423; cv=none; b=Mmyjaocmwo9P50Wl5saSAsjmqDAscCsLEJg2fI15woOUUtU9ZQKT+LvWhTbc402+pn4Ul71pzb+lu22MwxAVn4n0auv5GNtd+2ZxOubhS/gno+86FQXTA5RLCP3v+ZLkT9AVxTU0JL0FwEmbZsOKSRdtR0ubzpulmpzkI4ixawY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741891423; c=relaxed/simple; bh=AnfT/VgwnVX8MKBEmGtPgLoAZL9LC54ZxAW0nLdpCi8=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=TBmGAAc6xCednleYzPnSEiUNxUaUAAsuZwmKuh2ep6ziYFFBATNTR0iYbyAHQOXS/I/ztE5gZlcP9m96MOBXYbX0aRn++1ESempGH7PS9EluIxiJkJONBIFdz1iXPQS8bAKXKPqMEDGS1XcrHssleVMG+FjqgkyXwIK73RuQh3Q= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=DZrWnA+h; arc=none smtp.client-ip=170.10.133.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="DZrWnA+h" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1741891421; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=sL2IrnxwVclnb0cHanolDOhIAqLkrjlLeP84z0W88T4=; b=DZrWnA+hbcVXgyyUvv9aqHjvLipu+ei858j4aJvwqTgYeGtdXREB9DPOzyX4cEFsOZVSyT NV7HVkav/JYXrlHKNuoYV6Bxw5JvICL+OtbO5sc8bswvMy4jgtLSnEhx+zB10IhPTPlMqj IW0dYbQF7Zk9IgzlgicgUfQYYkU00e4= Received: from mx-prod-mc-02.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-368-y3DL6PIKMt-J6Fj92GpmHg-1; Thu, 13 Mar 2025 14:43:39 -0400 X-MC-Unique: y3DL6PIKMt-J6Fj92GpmHg-1 X-Mimecast-MFC-AGG-ID: y3DL6PIKMt-J6Fj92GpmHg_1741891417 Received: from mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.4]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-02.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 785821956087; Thu, 13 Mar 2025 18:43:37 +0000 (UTC) Received: from shalem.redhat.com (unknown [10.45.224.5]) by mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 898CF300377A; Thu, 13 Mar 2025 18:43:34 +0000 (UTC) From: Hans de Goede To: Sakari Ailus , Heimir Thor Sverrisson Cc: Hans de Goede , Stanislaw Gruszka , Ingvar Hagelund , Joachim Reichel , Bryan O'Donoghue , Hao Yao , Mauro Carvalho Chehab , linux-media@vger.kernel.org Subject: [PATCH v8 05/14] media: ov02c10: link-freq-index and pixel-rate fixes Date: Thu, 13 Mar 2025 19:43:05 +0100 Message-ID: <20250313184314.91410-6-hdegoede@redhat.com> In-Reply-To: <20250313184314.91410-1-hdegoede@redhat.com> References: <20250313184314.91410-1-hdegoede@redhat.com> Precedence: bulk X-Mailing-List: linux-media@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.4 link-freq-index and pixel-rate fixes: - The link_freq_index is (typically) not mode specific move it from the mode struct to the ov02c10 struct - Having one supported link-freq in bus_cfg.link_frequencies[] is enough switch to v4l2_link_freq_to_bitmap() to only require one match and store the first match in ov02c10->link_freq_index for use when setting up the controls - Use ov02c10->link_freq_index to set the value of the link-freq control - Note the above are no-ops because currently only 1 link-freq is supported - Use link-freq + lane-count to calculate the pixelrate instead of hard- coding it to 80MHz, this corrects the pixel-rate to 160MHz for 2 lanes - The link-freq and pixel-rate are set to a fixed value at probe() time and never change, drop the unnecessary setting of these controls from ov02c10_set_format() Signed-off-by: Hans de Goede --- drivers/media/i2c/ov02c10.c | 52 ++++++++++++++----------------------- 1 file changed, 19 insertions(+), 33 deletions(-) diff --git a/drivers/media/i2c/ov02c10.c b/drivers/media/i2c/ov02c10.c index ad5ab6c8a803..4b1b41f74ca2 100644 --- a/drivers/media/i2c/ov02c10.c +++ b/drivers/media/i2c/ov02c10.c @@ -16,9 +16,7 @@ #include #define OV02C10_LINK_FREQ_400MHZ 400000000ULL -#define OV02C10_SCLK 80000000LL #define OV02C10_MCLK 19200000 -#define OV02C10_DATA_LANES 1 #define OV02C10_RGB_DEPTH 10 #define OV02C10_REG_CHIP_ID CCI_REG16(0x300a) @@ -78,9 +76,6 @@ struct ov02c10_mode { /* Min vertical timining size */ u32 vts_min; - /* Link frequency needed for this resolution */ - u32 link_freq_index; - /* MIPI lanes used */ u8 mipi_lanes; @@ -409,7 +404,8 @@ struct ov02c10 { /* To serialize asynchronous callbacks */ struct mutex mutex; - /* MIPI lanes used */ + /* MIPI lane info */ + u32 link_freq_index; u8 mipi_lanes; /* Streaming on/off */ @@ -506,9 +502,8 @@ static int ov02c10_init_controls(struct ov02c10 *ov02c10) { struct v4l2_ctrl_handler *ctrl_hdlr; const struct ov02c10_mode *cur_mode; - s64 exposure_max, h_blank; + s64 exposure_max, h_blank, pixel_rate; u32 vblank_min, vblank_max, vblank_default; - int size; int ret = 0; ctrl_hdlr = &ov02c10->ctrl_handler; @@ -518,19 +513,22 @@ static int ov02c10_init_controls(struct ov02c10 *ov02c10) ctrl_hdlr->lock = &ov02c10->mutex; cur_mode = ov02c10->cur_mode; - size = ARRAY_SIZE(link_freq_menu_items); ov02c10->link_freq = v4l2_ctrl_new_int_menu(ctrl_hdlr, &ov02c10_ctrl_ops, V4L2_CID_LINK_FREQ, - size - 1, 0, + ov02c10->link_freq_index, 0, link_freq_menu_items); if (ov02c10->link_freq) ov02c10->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY; + /* MIPI lanes are DDR -> use link-freq * 2 */ + pixel_rate = link_freq_menu_items[ov02c10->link_freq_index] * 2 * + ov02c10->mipi_lanes / OV02C10_RGB_DEPTH; + ov02c10->pixel_rate = v4l2_ctrl_new_std(ctrl_hdlr, &ov02c10_ctrl_ops, V4L2_CID_PIXEL_RATE, 0, - OV02C10_SCLK, 1, OV02C10_SCLK); + pixel_rate, 1, pixel_rate); vblank_min = cur_mode->vts_min - cur_mode->height; vblank_max = OV02C10_VTS_MAX - cur_mode->height; @@ -801,8 +799,6 @@ static int ov02c10_set_format(struct v4l2_subdev *sd, *v4l2_subdev_state_get_format(sd_state, fmt->pad) = fmt->format; } else { ov02c10->cur_mode = mode; - __v4l2_ctrl_s_ctrl(ov02c10->link_freq, mode->link_freq_index); - __v4l2_ctrl_s_ctrl_int64(ov02c10->pixel_rate, OV02C10_SCLK); /* Update limits and set FPS to default */ vblank_def = mode->vts_def - mode->height; @@ -927,9 +923,9 @@ static int ov02c10_check_hwcfg(struct device *dev, struct ov02c10 *ov02c10) }; struct fwnode_handle *ep; struct fwnode_handle *fwnode = dev_fwnode(dev); - unsigned int i, j; - int ret; + unsigned long link_freq_bitmap; u32 ext_clk; + int ret; if (!fwnode) return -ENXIO; @@ -950,26 +946,16 @@ static int ov02c10_check_hwcfg(struct device *dev, struct ov02c10 *ov02c10) if (ret) return ret; - if (!bus_cfg.nr_of_link_frequencies) { - dev_err(dev, "no link frequencies defined"); - ret = -EINVAL; + ret = v4l2_link_freq_to_bitmap(dev, bus_cfg.link_frequencies, + bus_cfg.nr_of_link_frequencies, + link_freq_menu_items, + ARRAY_SIZE(link_freq_menu_items), + &link_freq_bitmap); + if (ret) goto out_err; - } - for (i = 0; i < ARRAY_SIZE(link_freq_menu_items); i++) { - for (j = 0; j < bus_cfg.nr_of_link_frequencies; j++) { - if (link_freq_menu_items[i] == - bus_cfg.link_frequencies[j]) - break; - } - - if (j == bus_cfg.nr_of_link_frequencies) { - dev_err(dev, "no link frequency %lld supported", - link_freq_menu_items[i]); - ret = -EINVAL; - goto out_err; - } - } + /* v4l2_link_freq_to_bitmap() guarantees at least 1 bit is set */ + ov02c10->link_freq_index = ffs(link_freq_bitmap) - 1; if (bus_cfg.bus.mipi_csi2.num_data_lanes != 2 && bus_cfg.bus.mipi_csi2.num_data_lanes != 4) { From patchwork Thu Mar 13 18:43:06 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hans de Goede X-Patchwork-Id: 14015792 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8F0791EF363 for ; Thu, 13 Mar 2025 18:43:44 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741891426; cv=none; b=IL4cwZZLI65eYkezVT20/6F1UogvvI6qQbqgCzLwzZ5tWOQIn1eDjNkG+iMYqmUQZfx9Sxx2GIan4CnXLJKQZigd/DVs2CxsrG6nXBVSH/NyWUD7c6j6E12UiK7vmPUcW1I+1NkjHHFjKcPNTx6Kcad3HAcqXqT/1ocVeYFq2tA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741891426; c=relaxed/simple; bh=Mb9fkzRdoJS1PvLxX3EgtGaGXc5/2dnzzjCcgsS6lTY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Hpx6IOXghUw50dC5ySIP2w1w0NKknyaniHDW4I+bx3mFd9K98s/8aHkmgyvnxDkzF8aMDIe1Hrisd1y3Po2tKMzdvXv5bLqtPuiNkmscoxnbZPq1WkgUqJLuOhIrrOJgpytVvDaikFRiIOvnE6EyjjgwDenef8+MdXRfJ5TmS54= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=UNpafNSo; arc=none smtp.client-ip=170.10.129.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="UNpafNSo" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1741891423; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Cl93H+ENlRD2MtPsMlsIzDedHC89AjIG8eNVkzppe3c=; b=UNpafNSoX8mPftxpGxytRrwHKHrXyS4lB26pBODTHbwpjnujUmKXU/DPNFZTQoqow58F6Y Y4GGMVP1oX5Rw/1OKwE0UY+rBLlNIXmvkuMa3IL9i3D+WGyvCF9DAjfn28VvAg+CeepfHL 1wzeZZJzwIE17+d9RR053WCnPFbUG1o= Received: from mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-55-zspREh7zPT2wPlkhe09ECQ-1; Thu, 13 Mar 2025 14:43:42 -0400 X-MC-Unique: zspREh7zPT2wPlkhe09ECQ-1 X-Mimecast-MFC-AGG-ID: zspREh7zPT2wPlkhe09ECQ_1741891420 Received: from mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.4]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id C8D221800EC5; Thu, 13 Mar 2025 18:43:40 +0000 (UTC) Received: from shalem.redhat.com (unknown [10.45.224.5]) by mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id E6960300376F; Thu, 13 Mar 2025 18:43:37 +0000 (UTC) From: Hans de Goede To: Sakari Ailus , Heimir Thor Sverrisson Cc: Hans de Goede , Stanislaw Gruszka , Ingvar Hagelund , Joachim Reichel , Bryan O'Donoghue , Hao Yao , Mauro Carvalho Chehab , linux-media@vger.kernel.org Subject: [PATCH v8 06/14] media: ov02c10: ov02c10_check_hwcfg() improvements Date: Thu, 13 Mar 2025 19:43:06 +0100 Message-ID: <20250313184314.91410-7-hdegoede@redhat.com> In-Reply-To: <20250313184314.91410-1-hdegoede@redhat.com> References: <20250313184314.91410-1-hdegoede@redhat.com> Precedence: bulk X-Mailing-List: linux-media@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.4 ov02c10_check_hwcfg() improvements: - Drop unnecessary return -ENXIO when there is no fwnode, this is already caught by the fwnode_graph_get_next_endpoint() call - Use dev_err_probe() in ov02c10_check_hwcfg() - Make sure all error messages have '\n' at the end - Add missing fwnode_handle_put() on clock-frequency read errors - Check clock-frequency matches OV02C10_MCLK - Log an error on v4l2_fwnode_endpoint_alloc_parse() failure - ov02c10 code supports 1 or 2 lane setups not 2 or 4 lane setups - replace return -EINVAL no mipi-lanes mismatch with goto check_hwcfg_error to properly free the bus_cfg - Don't log an error in probe() when ov02c10_check_hwcfg() fails, in all cases ov02c10_check_hwcfg() already logs an error using dev_probe_err() and if the error is -EPROBE_DEFER then we don't want to keep logging that multiple times until the dependency is resolved (dev_probe_err() suppresses logging for -EPROBE_DEFER errors) Signed-off-by: Hans de Goede --- drivers/media/i2c/ov02c10.c | 55 +++++++++++++++++++++---------------- 1 file changed, 31 insertions(+), 24 deletions(-) diff --git a/drivers/media/i2c/ov02c10.c b/drivers/media/i2c/ov02c10.c index 4b1b41f74ca2..a6ea747243e6 100644 --- a/drivers/media/i2c/ov02c10.c +++ b/drivers/media/i2c/ov02c10.c @@ -921,30 +921,38 @@ static int ov02c10_check_hwcfg(struct device *dev, struct ov02c10 *ov02c10) struct v4l2_fwnode_endpoint bus_cfg = { .bus_type = V4L2_MBUS_CSI2_DPHY }; - struct fwnode_handle *ep; - struct fwnode_handle *fwnode = dev_fwnode(dev); + struct fwnode_handle *ep, *fwnode = dev_fwnode(dev); unsigned long link_freq_bitmap; - u32 ext_clk; + u32 mclk; int ret; - if (!fwnode) - return -ENXIO; - - ep = fwnode_graph_get_next_endpoint(fwnode, NULL); + /* + * Sometimes the fwnode graph is initialized by the bridge driver, + * wait for this. + */ + ep = fwnode_graph_get_endpoint_by_id(fwnode, 0, 0, 0); if (!ep) - return -EPROBE_DEFER; + return dev_err_probe(dev, -EPROBE_DEFER, + "waiting for fwnode graph endpoint\n"); - ret = fwnode_property_read_u32(dev_fwnode(dev), "clock-frequency", - &ext_clk); + ret = fwnode_property_read_u32(fwnode, "clock-frequency", &mclk); if (ret) { - dev_err(dev, "can't get clock frequency"); - return ret; + fwnode_handle_put(ep); + return dev_err_probe(dev, ret, + "reading clock-frequency property\n"); + } + + if (mclk != OV02C10_MCLK) { + fwnode_handle_put(ep); + return dev_err_probe(dev, -EINVAL, + "external clock %u is not supported\n", + mclk); } ret = v4l2_fwnode_endpoint_alloc_parse(ep, &bus_cfg); fwnode_handle_put(ep); if (ret) - return ret; + return dev_err_probe(dev, ret, "parsing endpoint failed\n"); ret = v4l2_link_freq_to_bitmap(dev, bus_cfg.link_frequencies, bus_cfg.nr_of_link_frequencies, @@ -952,22 +960,23 @@ static int ov02c10_check_hwcfg(struct device *dev, struct ov02c10 *ov02c10) ARRAY_SIZE(link_freq_menu_items), &link_freq_bitmap); if (ret) - goto out_err; + goto check_hwcfg_error; /* v4l2_link_freq_to_bitmap() guarantees at least 1 bit is set */ ov02c10->link_freq_index = ffs(link_freq_bitmap) - 1; - if (bus_cfg.bus.mipi_csi2.num_data_lanes != 2 && - bus_cfg.bus.mipi_csi2.num_data_lanes != 4) { - dev_err(dev, "number of CSI2 data lanes %d is not supported", - bus_cfg.bus.mipi_csi2.num_data_lanes); - return(-EINVAL); + if (bus_cfg.bus.mipi_csi2.num_data_lanes != 1 && + bus_cfg.bus.mipi_csi2.num_data_lanes != 2) { + ret = dev_err_probe(dev, -EINVAL, + "number of CSI2 data lanes %u is not supported\n", + bus_cfg.bus.mipi_csi2.num_data_lanes); + goto check_hwcfg_error; } + ov02c10->mipi_lanes = bus_cfg.bus.mipi_csi2.num_data_lanes; -out_err: +check_hwcfg_error: v4l2_fwnode_endpoint_free(&bus_cfg); - return ret; } @@ -994,10 +1003,8 @@ static int ov02c10_probe(struct i2c_client *client) /* Check HW config */ ret = ov02c10_check_hwcfg(&client->dev, ov02c10); - if (ret) { - dev_err(&client->dev, "failed to check hwcfg: %d", ret); + if (ret) return ret; - } v4l2_i2c_subdev_init(&ov02c10->sd, client, &ov02c10_subdev_ops); ov02c10_get_pm_resources(&client->dev); From patchwork Thu Mar 13 18:43:07 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hans de Goede X-Patchwork-Id: 14015793 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id BC3FF1EEA51 for ; Thu, 13 Mar 2025 18:43:47 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741891429; cv=none; b=F9kSd76z4l1OsXGBSDk+c0aq8qYNQfft4KUOf4D1m0R5hqiSwofh+q0rn09lcBijUqn2ed7EPWeSQN/59c4wP+cbVlpocRYFFLGcRBcfAgf9oqi+VFAcrd/fungqDplVxSV0vndLameJiUIO33/XuvL1bt4xTEiPd1Bie+f4T+w= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741891429; c=relaxed/simple; bh=Ic1kKssEI0uaaEraaU6gsgRVC3jZNN3pJZDwTqt1uIE=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=aaQH36eBifVRG6PbYvUM8lb70TIXsfHYFYwkX++xLMd6MkYnsa7G774IgwIVqqtfTCbQBgMiu9dK6KuDsslqsO8W30uh4QfLvZAQHzwE7NTSvFTOGFTKMcsT28l32gBWE5BIRdbVQBl/WkbVUwwc5JoIcBudpyrvokQnpfPqHIc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=ZP8WsYtW; arc=none smtp.client-ip=170.10.133.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="ZP8WsYtW" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1741891427; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=bD+mqbgkHA0PlnzJdZdo2V3QIhUAmxPfhQd5ON0+tGI=; b=ZP8WsYtWTsrlC7FFtNkGOt13Lh/+SBHBaML52Y6O/6+v8HTjyRJERWHiRBmh+R1Q7TwZUy tgIaaZf+j12etMTsG165hQ2ecRacTtXRPj2w9EKGFxdQ5qzWSP3h2VjODpTbuIPLfZ4Kjd xJNsL57uRkIAKkC+PTWmXHb4Zo+ZgxI= Received: from mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-120-f15o8LhFP5mqXObQEeQk_w-1; Thu, 13 Mar 2025 14:43:45 -0400 X-MC-Unique: f15o8LhFP5mqXObQEeQk_w-1 X-Mimecast-MFC-AGG-ID: f15o8LhFP5mqXObQEeQk_w_1741891424 Received: from mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.4]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 25C161956046; Thu, 13 Mar 2025 18:43:44 +0000 (UTC) Received: from shalem.redhat.com (unknown [10.45.224.5]) by mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 434A5300376F; Thu, 13 Mar 2025 18:43:41 +0000 (UTC) From: Hans de Goede To: Sakari Ailus , Heimir Thor Sverrisson Cc: Hans de Goede , Stanislaw Gruszka , Ingvar Hagelund , Joachim Reichel , Bryan O'Donoghue , Hao Yao , Mauro Carvalho Chehab , linux-media@vger.kernel.org Subject: [PATCH v8 07/14] media: ov02c10: CCI usage fixes Date: Thu, 13 Mar 2025 19:43:07 +0100 Message-ID: <20250313184314.91410-8-hdegoede@redhat.com> In-Reply-To: <20250313184314.91410-1-hdegoede@redhat.com> References: <20250313184314.91410-1-hdegoede@redhat.com> Precedence: bulk X-Mailing-List: linux-media@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.4 Several fixes to ov02c10's usage of the CCI helpers: - Fix indentation of some cci_*() calls - Make sure logged register writing errors end with '\n' - CCI functions already log errors themselves, drop error logging for them - CCI functions being passed &ret as last argument can be chained without need to check ret in between, if ret != 0 then the next CCI call(s) will be a no-op - err/&ret argument passed to cci_*() functions should be signed - Move devm_cci_regmap_init_i2c() to ov02c10_probe() and add error check Signed-off-by: Hans de Goede --- drivers/media/i2c/ov02c10.c | 30 ++++++++++-------------------- 1 file changed, 10 insertions(+), 20 deletions(-) diff --git a/drivers/media/i2c/ov02c10.c b/drivers/media/i2c/ov02c10.c index a6ea747243e6..b9f28368e29f 100644 --- a/drivers/media/i2c/ov02c10.c +++ b/drivers/media/i2c/ov02c10.c @@ -423,16 +423,12 @@ static int ov02c10_test_pattern(struct ov02c10 *ov02c10, int pattern) if (!pattern) return cci_update_bits(ov02c10->regmap, OV02C10_REG_TEST_PATTERN, - BIT(7), 0, NULL); + BIT(7), 0, NULL); cci_update_bits(ov02c10->regmap, OV02C10_REG_TEST_PATTERN, 0x03, pattern - 1, &ret); - if (ret) - return ret; - cci_update_bits(ov02c10->regmap, OV02C10_REG_TEST_PATTERN, BIT(7), OV02C10_TEST_PATTERN_ENABLE, &ret); - return ret; } @@ -590,7 +586,7 @@ static int ov02c10_start_streaming(struct ov02c10 *ov02c10) ret = regmap_multi_reg_write(ov02c10->regmap, reg_sequence, sequence_length); if (ret) { - dev_err(&client->dev, "failed to set mode"); + dev_err(&client->dev, "failed to set mode\n"); return ret; } @@ -607,21 +603,12 @@ static int ov02c10_start_streaming(struct ov02c10 *ov02c10) if (ret) return ret; - ret = cci_write(ov02c10->regmap, OV02C10_REG_STREAM_CONTROL, 1, NULL); - if (ret) - dev_err(&client->dev, "failed to start streaming"); - - return ret; + return cci_write(ov02c10->regmap, OV02C10_REG_STREAM_CONTROL, 1, NULL); } static void ov02c10_stop_streaming(struct ov02c10 *ov02c10) { - struct i2c_client *client = v4l2_get_subdevdata(&ov02c10->sd); - int ret = 0; - - ret = cci_write(ov02c10->regmap, OV02C10_REG_STREAM_CONTROL, 0, NULL); - if (ret) - dev_err(&client->dev, "failed to stop streaming"); + cci_write(ov02c10->regmap, OV02C10_REG_STREAM_CONTROL, 0, NULL); } static int ov02c10_set_stream(struct v4l2_subdev *sd, int enable) @@ -900,10 +887,9 @@ static int ov02c10_identify_module(struct ov02c10 *ov02c10) { struct i2c_client *client = v4l2_get_subdevdata(&ov02c10->sd); u64 chip_id; - u32 ret = 0; + int ret; - ov02c10->regmap = devm_cci_regmap_init_i2c(client, 16); - cci_read(ov02c10->regmap, OV02C10_REG_CHIP_ID, &chip_id, &ret); + ret = cci_read(ov02c10->regmap, OV02C10_REG_CHIP_ID, &chip_id, NULL); if (ret) return ret; @@ -1009,6 +995,10 @@ static int ov02c10_probe(struct i2c_client *client) v4l2_i2c_subdev_init(&ov02c10->sd, client, &ov02c10_subdev_ops); ov02c10_get_pm_resources(&client->dev); + ov02c10->regmap = devm_cci_regmap_init_i2c(client, 16); + if (IS_ERR(ov02c10->regmap)) + return PTR_ERR(ov02c10->regmap); + ret = ov02c10_power_on(&client->dev); if (ret) { dev_err_probe(&client->dev, ret, "failed to power on\n"); From patchwork Thu Mar 13 18:43:08 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hans de Goede X-Patchwork-Id: 14015794 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 57B2A1DB54C for ; Thu, 13 Mar 2025 18:43:54 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741891436; cv=none; b=F1nkTFKSA6B+z0cN0boqH80pxxZbaZ8eeRVNYyFuft9XKtqi1DvLcvvjLowU2S+EIHJA7Ofkv+AGyp1GAox+9Ns/lqmI//xkuDLvIauzBlbiyGLNxCXRcJ9l1nOWttet1K8/botzTlj6jSjG+kwQ6vFvvtiS09UpBDTzcppzxYo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741891436; c=relaxed/simple; bh=TyCrM0iNFxYyBXKhzg8Db58rlTNHKgZ3OVwlqu+AJVk=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=TxfTJROP7J33TJUslx6Y4BlvmZ2DSZU4+aPu8lcgvr3Z1y4uKcngVE9qNiCohxaMNeiHNbNx8SzV3ZsBYFc7rmZdA0lbSOl2TL/hlxQgYMHL8Kq8dgg9ydcvmQhqbgWGGLpNW6tVU0GQBCmzrihNtmayVfljTA8F5zjcEqMof+A= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=Qoze3pZo; arc=none smtp.client-ip=170.10.129.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="Qoze3pZo" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1741891433; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=33NHCMQTlmTS51f+KPkZJsq6MZ8F2AqedGUCxOeA6aI=; b=Qoze3pZo40IRavIk1nkINFiEh0a4Ls3NZal2MdaSEdjwbXRjoFKvnFKl5EVficoO19KpY5 W4Hr1p9N0MBtg/qjNQP48rqx8DCN79kjE93GVWqOEjoe3198ZNBjYFJJDwI61CbdO2U7Qx CZ5PI6saXp2y1HiioVdhZnmspLzkYDM= Received: from mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-93-KJngkfvqMWiGZ4_1zvLZlg-1; Thu, 13 Mar 2025 14:43:49 -0400 X-MC-Unique: KJngkfvqMWiGZ4_1zvLZlg-1 X-Mimecast-MFC-AGG-ID: KJngkfvqMWiGZ4_1zvLZlg_1741891427 Received: from mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.4]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 7FA9B195608F; Thu, 13 Mar 2025 18:43:47 +0000 (UTC) Received: from shalem.redhat.com (unknown [10.45.224.5]) by mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 94831300376F; Thu, 13 Mar 2025 18:43:44 +0000 (UTC) From: Hans de Goede To: Sakari Ailus , Heimir Thor Sverrisson Cc: Hans de Goede , Stanislaw Gruszka , Ingvar Hagelund , Joachim Reichel , Bryan O'Donoghue , Hao Yao , Mauro Carvalho Chehab , linux-media@vger.kernel.org Subject: [PATCH v8 08/14] media: ov02c10: Make modes lane-count independent Date: Thu, 13 Mar 2025 19:43:08 +0100 Message-ID: <20250313184314.91410-9-hdegoede@redhat.com> In-Reply-To: <20250313184314.91410-1-hdegoede@redhat.com> References: <20250313184314.91410-1-hdegoede@redhat.com> Precedence: bulk X-Mailing-List: linux-media@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.4 ATM the driver only supports one mode (1928x1092) but before this change the supported_modes[] had 2 entries, 1 for 1928x1092 when using 1 mipi lane and 1 for 1928x1092 when using 2 mipi lanes. This causes enum_framesizes returning 2 1928x1092 modes, instead make it one mode and dynamically adapt for the number of lanes in ov02c10_start_streaming() and ov02c10_set_format(). Signed-off-by: Hans de Goede --- drivers/media/i2c/ov02c10.c | 63 ++++++++++++++++--------------------- 1 file changed, 27 insertions(+), 36 deletions(-) diff --git a/drivers/media/i2c/ov02c10.c b/drivers/media/i2c/ov02c10.c index b9f28368e29f..e1013d1da459 100644 --- a/drivers/media/i2c/ov02c10.c +++ b/drivers/media/i2c/ov02c10.c @@ -70,21 +70,15 @@ struct ov02c10_mode { /* Horizontal timining size */ u32 hts; - /* Default vertical timining size */ - u32 vts_def; - /* Min vertical timining size */ u32 vts_min; - /* MIPI lanes used */ - u8 mipi_lanes; - /* Sensor register settings for this resolution */ const struct reg_sequence *reg_sequence; const int sequence_length; /* Sensor register settings for 1 or 2 lane config */ - const struct reg_sequence *lane_settings; - const int lane_settings_length; + const struct reg_sequence *lane_settings[2]; + const int lane_settings_length[2]; }; static const struct reg_sequence sensor_1928x1092_30fps_setting[] = { @@ -358,25 +352,17 @@ static const struct ov02c10_mode supported_modes[] = { .width = 1928, .height = 1092, .hts = 2280, - .vts_def = 1164, .vts_min = 1164, - .mipi_lanes = 1, .reg_sequence = sensor_1928x1092_30fps_setting, .sequence_length = ARRAY_SIZE(sensor_1928x1092_30fps_setting), - .lane_settings = sensor_1928x1092_30fps_1lane_setting, - .lane_settings_length = ARRAY_SIZE(sensor_1928x1092_30fps_1lane_setting), - }, - { - .width = 1928, - .height = 1092, - .hts = 2280, - .vts_def = 2328, - .vts_min = 1164, - .mipi_lanes = 2, - .reg_sequence = sensor_1928x1092_30fps_setting, - .sequence_length = ARRAY_SIZE(sensor_1928x1092_30fps_setting), - .lane_settings = sensor_1928x1092_30fps_2lane_setting, - .lane_settings_length = ARRAY_SIZE(sensor_1928x1092_30fps_2lane_setting), + .lane_settings = { + sensor_1928x1092_30fps_1lane_setting, + sensor_1928x1092_30fps_2lane_setting + }, + .lane_settings_length = { + ARRAY_SIZE(sensor_1928x1092_30fps_1lane_setting), + ARRAY_SIZE(sensor_1928x1092_30fps_2lane_setting), + }, }, }; @@ -499,7 +485,7 @@ static int ov02c10_init_controls(struct ov02c10 *ov02c10) struct v4l2_ctrl_handler *ctrl_hdlr; const struct ov02c10_mode *cur_mode; s64 exposure_max, h_blank, pixel_rate; - u32 vblank_min, vblank_max, vblank_default; + u32 vblank_min, vblank_max, vblank_default, vts_def; int ret = 0; ctrl_hdlr = &ov02c10->ctrl_handler; @@ -526,9 +512,15 @@ static int ov02c10_init_controls(struct ov02c10 *ov02c10) V4L2_CID_PIXEL_RATE, 0, pixel_rate, 1, pixel_rate); + /* + * For default multiple min by number of lanes to keep the default + * FPS the same indepenedent of the lane count. + */ + vts_def = cur_mode->vts_min * ov02c10->mipi_lanes; + vblank_min = cur_mode->vts_min - cur_mode->height; vblank_max = OV02C10_VTS_MAX - cur_mode->height; - vblank_default = cur_mode->vts_def - cur_mode->height; + vblank_default = vts_def - cur_mode->height; ov02c10->vblank = v4l2_ctrl_new_std(ctrl_hdlr, &ov02c10_ctrl_ops, V4L2_CID_VBLANK, vblank_min, vblank_max, 1, vblank_default); @@ -546,7 +538,7 @@ static int ov02c10_init_controls(struct ov02c10 *ov02c10) v4l2_ctrl_new_std(ctrl_hdlr, &ov02c10_ctrl_ops, V4L2_CID_DIGITAL_GAIN, OV02C10_DGTL_GAIN_MIN, OV02C10_DGTL_GAIN_MAX, OV02C10_DGTL_GAIN_STEP, OV02C10_DGTL_GAIN_DEFAULT); - exposure_max = cur_mode->vts_def - OV02C10_EXPOSURE_MAX_MARGIN; + exposure_max = vts_def - OV02C10_EXPOSURE_MAX_MARGIN; ov02c10->exposure = v4l2_ctrl_new_std(ctrl_hdlr, &ov02c10_ctrl_ops, V4L2_CID_EXPOSURE, OV02C10_EXPOSURE_MIN, @@ -590,8 +582,8 @@ static int ov02c10_start_streaming(struct ov02c10 *ov02c10) return ret; } - reg_sequence = ov02c10->cur_mode->lane_settings; - sequence_length = ov02c10->cur_mode->lane_settings_length; + reg_sequence = ov02c10->cur_mode->lane_settings[ov02c10->mipi_lanes - 1]; + sequence_length = ov02c10->cur_mode->lane_settings_length[ov02c10->mipi_lanes - 1]; ret = regmap_multi_reg_write(ov02c10->regmap, reg_sequence, sequence_length); if (ret) { @@ -775,10 +767,10 @@ static int ov02c10_set_format(struct v4l2_subdev *sd, const struct ov02c10_mode *mode; s32 vblank_def, h_blank; - if (ov02c10->mipi_lanes == 1) - mode = &supported_modes[0]; - else - mode = &supported_modes[1]; + mode = v4l2_find_nearest_size(supported_modes, + ARRAY_SIZE(supported_modes), width, + height, fmt->format.width, + fmt->format.height); mutex_lock(&ov02c10->mutex); ov02c10_update_pad_format(mode, &fmt->format); @@ -788,7 +780,7 @@ static int ov02c10_set_format(struct v4l2_subdev *sd, ov02c10->cur_mode = mode; /* Update limits and set FPS to default */ - vblank_def = mode->vts_def - mode->height; + vblank_def = mode->vts_min * ov02c10->mipi_lanes - mode->height; __v4l2_ctrl_modify_range(ov02c10->vblank, mode->vts_min - mode->height, OV02C10_VTS_MAX - mode->height, 1, @@ -1013,8 +1005,7 @@ static int ov02c10_probe(struct i2c_client *client) mutex_init(&ov02c10->mutex); ov02c10->cur_mode = &supported_modes[0]; - if (ov02c10->mipi_lanes == 2) - ov02c10->cur_mode = &supported_modes[1]; + ret = ov02c10_init_controls(ov02c10); if (ret) { dev_err(&client->dev, "failed to init controls: %d", ret); From patchwork Thu Mar 13 18:43:09 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hans de Goede X-Patchwork-Id: 14015795 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 12D831DB54C for ; Thu, 13 Mar 2025 18:43:56 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741891438; cv=none; b=Pk7sl8MM1uHV4hQuoByTTM0bTkXQx5Fe7fwmKOZS3Qgvl8/PwJriY+MpFZJZFl1W17Ju67pAOulJgjmHeRQ9M8jc9VEIntNNJbrYNTXIqadaGECmq3dbgPhBsAtwndvmW9A116cB4tUju7pELnnGt01gyIz2B/RctTWgEWjHPxA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741891438; c=relaxed/simple; bh=8XiRRiNygpEzXFkkRpMgTh2t6F/SwQN/JzhoYD2aYho=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Df2b7jZOtEQyuAuu1XVyfys2FLeM+yvx2NuLQL/RL78Xdx0GHccI4wIJLmG/dRD5VtqHFR9AQwcMp8cjCm0jbMChCnDQxCFK6ekbT/WtKLk2wM1BWcg11/zMBhSc+vxdFEYHjd9QlfB+GqeiWuPqHn+/B5o4uPP8E0Wr1rkMM4U= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=BBC3qf9F; arc=none smtp.client-ip=170.10.129.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="BBC3qf9F" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1741891436; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=nUQq2u6HJXDhjKFKEjw5GKkTc2CdO8qyh1g3cVuHUQ4=; b=BBC3qf9FyKxuZxIuwCI3jw3aH5u+YGcs2iZuf2y23opFnXO3t9Tst5QVA7QIV0P4PYVIRi fYiaToPa4zafQrOibQ/XUxiy53hJu3xS9JPUgslM+REYXPEbr+tvXvUEKvNEdsjNhOPkID YWYmdhsVOYTwWKeCQn9P84lLwO12Hd8= Received: from mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-681-sflWXWG3MLmqxAAjDeNUKA-1; Thu, 13 Mar 2025 14:43:52 -0400 X-MC-Unique: sflWXWG3MLmqxAAjDeNUKA-1 X-Mimecast-MFC-AGG-ID: sflWXWG3MLmqxAAjDeNUKA_1741891430 Received: from mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.4]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id CDC0E180AF52; Thu, 13 Mar 2025 18:43:50 +0000 (UTC) Received: from shalem.redhat.com (unknown [10.45.224.5]) by mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id E66B2300376F; Thu, 13 Mar 2025 18:43:47 +0000 (UTC) From: Hans de Goede To: Sakari Ailus , Heimir Thor Sverrisson Cc: Hans de Goede , Stanislaw Gruszka , Ingvar Hagelund , Joachim Reichel , Bryan O'Donoghue , Hao Yao , Mauro Carvalho Chehab , linux-media@vger.kernel.org Subject: [PATCH v8 09/14] media: ov02c10: Drop handshake pin support Date: Thu, 13 Mar 2025 19:43:09 +0100 Message-ID: <20250313184314.91410-10-hdegoede@redhat.com> In-Reply-To: <20250313184314.91410-1-hdegoede@redhat.com> References: <20250313184314.91410-1-hdegoede@redhat.com> Precedence: bulk X-Mailing-List: linux-media@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.4 The handshake GPIO is not a sensor GPIO but is related to the special Lattice MIPI aggregator chip found on some Intel IPU6/IPU7 laptops. Since this is not a sensor GPIO it should not be handled by the sensor driver. See here for the alternative plan to handle this: https://lore.kernel.org/linux-media/4b87a956-a767-48dc-b98b-f80d9a44adc8@redhat.com/ Signed-off-by: Hans de Goede --- drivers/media/i2c/ov02c10.c | 19 +++---------------- 1 file changed, 3 insertions(+), 16 deletions(-) diff --git a/drivers/media/i2c/ov02c10.c b/drivers/media/i2c/ov02c10.c index e1013d1da459..38918b1b6a95 100644 --- a/drivers/media/i2c/ov02c10.c +++ b/drivers/media/i2c/ov02c10.c @@ -382,7 +382,6 @@ struct ov02c10 { struct clk *img_clk; struct regulator *avdd; struct gpio_desc *reset; - struct gpio_desc *handshake; /* Current mode */ const struct ov02c10_mode *cur_mode; @@ -650,12 +649,6 @@ static int ov02c10_get_pm_resources(struct device *dev) return dev_err_probe(dev, PTR_ERR(ov02c10->reset), "failed to get reset gpio\n"); - ov02c10->handshake = devm_gpiod_get_optional(dev, "handshake", - GPIOD_OUT_LOW); - if (IS_ERR(ov02c10->handshake)) - return dev_err_probe(dev, PTR_ERR(ov02c10->handshake), - "failed to get handshake gpio\n"); - ov02c10->img_clk = devm_clk_get_optional(dev, NULL); if (IS_ERR(ov02c10->img_clk)) return dev_err_probe(dev, PTR_ERR(ov02c10->img_clk), @@ -680,7 +673,6 @@ static int ov02c10_power_off(struct device *dev) int ret = 0; gpiod_set_value_cansleep(ov02c10->reset, 1); - gpiod_set_value_cansleep(ov02c10->handshake, 0); if (ov02c10->avdd) ret = regulator_disable(ov02c10->avdd); @@ -710,16 +702,11 @@ static int ov02c10_power_on(struct device *dev) return ret; } } - gpiod_set_value_cansleep(ov02c10->handshake, 1); + gpiod_set_value_cansleep(ov02c10->reset, 0); + usleep_range(1500, 1800); - /* Lattice MIPI aggregator with some version FW needs longer delay - * after handshake triggered. We set 25ms as a safe value and wait - * for a stable version FW. - */ - msleep_interruptible(25); - - return ret; + return 0; } static int __maybe_unused ov02c10_suspend(struct device *dev) From patchwork Thu Mar 13 18:43:10 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hans de Goede X-Patchwork-Id: 14015796 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5E9541DB54C for ; Thu, 13 Mar 2025 18:44:00 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741891441; cv=none; b=nEpwiZuEsp/Gggrkk1+5/DjuVTKuzxqgJUXfEYmznIov4uO+rCi0kflBtKb85YjOVNVY51rPCrgDqQd0BAg2UPJT+uBWU4fXVJgWlulIoBybbaKOj8oEhtQNOe3RzCfeS/WO8ahvKtyrwJioaTRYI+WsVKlZdpNES7sv77bPEVY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741891441; c=relaxed/simple; bh=DIyGsatYkhoePTrU7WidzwRugLZOZ3AE05ZtLutDKxM=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=dcbHGaZEu+AI7Fc2f0E+h+5NW7WM1GBh+ni+6Lr9r6+etQY4H4i0N24W8UNvXRWaDoGTNEoiaVHZd2Uwl5LrQLCT/3L8m2qPpIz2Rwne/m78FoIgErqYlXKwzXjUx5pdGNFanA9fITj4jBfYVodp9OXYqzEwfXKla1Fm9/yPwP8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=FN5qFqyi; arc=none smtp.client-ip=170.10.129.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="FN5qFqyi" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1741891439; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=wKcsmW384YnM7IYtDAT4hSYR7b+myO/wAdDVChhWqwo=; b=FN5qFqyibVpstzetdKinZTX18pOHsId9vs5N2zGJpE4dvQt3tJNm34MbZbPo3djy5zVO4W 3bMFgJEr/FplKq5ZBfOyyg3Et+jl+PFYIwouTRVlSerlnd73bsTredb5CJpXcZP5Kr1vv/ G0hSB2/I1CvrH3U/9IUco4whcgsWM54= Received: from mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-599-cA5W91IBN5mtZMQqq3pVLQ-1; Thu, 13 Mar 2025 14:43:55 -0400 X-MC-Unique: cA5W91IBN5mtZMQqq3pVLQ-1 X-Mimecast-MFC-AGG-ID: cA5W91IBN5mtZMQqq3pVLQ_1741891434 Received: from mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.4]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 2B5D1180AF4E; Thu, 13 Mar 2025 18:43:54 +0000 (UTC) Received: from shalem.redhat.com (unknown [10.45.224.5]) by mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 47EFD3003770; Thu, 13 Mar 2025 18:43:51 +0000 (UTC) From: Hans de Goede To: Sakari Ailus , Heimir Thor Sverrisson Cc: Hans de Goede , Stanislaw Gruszka , Ingvar Hagelund , Joachim Reichel , Bryan O'Donoghue , Hao Yao , Mauro Carvalho Chehab , linux-media@vger.kernel.org Subject: [PATCH v8 10/14] media: ov02c10: ov02c10_get_pm_resources() fixes Date: Thu, 13 Mar 2025 19:43:10 +0100 Message-ID: <20250313184314.91410-11-hdegoede@redhat.com> In-Reply-To: <20250313184314.91410-1-hdegoede@redhat.com> References: <20250313184314.91410-1-hdegoede@redhat.com> Precedence: bulk X-Mailing-List: linux-media@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.4 A set of ov02c10_get_pm_resources() fixes: 1. Reset should only be de-asserted after enabling the regulators and clocks. Request the reset GPIO with GPIOD_OUT_HIGH and on success sleep for 1 ms to ensure that it is asserted for at least 1 ms before ov02c10_power_on() de-asserts it. 2. Use plain devm_regulator_get() for avdd. 3. Add error checking to the ov02c10_get_pm_resources() call in probe(), it may fail with -EPROBE_DEFER. 4. While at it move the v4l2_i2c_subdev_init() call to directly after allocating the ov02c10 struct, it has nothing to do with the ov02c10_get_pm_resources() call. Signed-off-by: Hans de Goede --- drivers/media/i2c/ov02c10.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/drivers/media/i2c/ov02c10.c b/drivers/media/i2c/ov02c10.c index 38918b1b6a95..a46cacf301a2 100644 --- a/drivers/media/i2c/ov02c10.c +++ b/drivers/media/i2c/ov02c10.c @@ -642,26 +642,23 @@ static int ov02c10_get_pm_resources(struct device *dev) { struct v4l2_subdev *sd = dev_get_drvdata(dev); struct ov02c10 *ov02c10 = to_ov02c10(sd); - int ret; - ov02c10->reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW); + ov02c10->reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH); if (IS_ERR(ov02c10->reset)) return dev_err_probe(dev, PTR_ERR(ov02c10->reset), "failed to get reset gpio\n"); + if (ov02c10->reset) + fsleep(1000); ov02c10->img_clk = devm_clk_get_optional(dev, NULL); if (IS_ERR(ov02c10->img_clk)) return dev_err_probe(dev, PTR_ERR(ov02c10->img_clk), "failed to get imaging clock\n"); - ov02c10->avdd = devm_regulator_get_optional(dev, "avdd"); - if (IS_ERR(ov02c10->avdd)) { - ret = PTR_ERR(ov02c10->avdd); - ov02c10->avdd = NULL; - if (ret != -ENODEV) - return dev_err_probe(dev, ret, - "failed to get avdd regulator\n"); - } + ov02c10->avdd = devm_regulator_get(dev, "avdd"); + if (IS_ERR(ov02c10->avdd)) + return dev_err_probe(dev, PTR_ERR(ov02c10->avdd), + "failed to get avdd regulator\n"); return 0; } @@ -966,13 +963,16 @@ static int ov02c10_probe(struct i2c_client *client) if (!ov02c10) return -ENOMEM; + v4l2_i2c_subdev_init(&ov02c10->sd, client, &ov02c10_subdev_ops); + /* Check HW config */ ret = ov02c10_check_hwcfg(&client->dev, ov02c10); if (ret) return ret; - v4l2_i2c_subdev_init(&ov02c10->sd, client, &ov02c10_subdev_ops); - ov02c10_get_pm_resources(&client->dev); + ret = ov02c10_get_pm_resources(&client->dev); + if (ret) + return ret; ov02c10->regmap = devm_cci_regmap_init_i2c(client, 16); if (IS_ERR(ov02c10->regmap)) From patchwork Thu Mar 13 18:43:11 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hans de Goede X-Patchwork-Id: 14015797 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 323211EFF9F for ; Thu, 13 Mar 2025 18:44:02 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741891447; cv=none; b=W8TbDucPHouVh2AjP+eUE1KC0jxbzuyEts0IqFrPE5P8P4kLFKElHAzbjaPsCbwqkvow0Niv94QDA5Jko+brT0o4YdwemXxQCI29iCDQejdApTpfikO60X06VtXrk4e9zUODbbeWBsJyXcYnaZMY11+booTkus0jgeyWKURXfZI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741891447; c=relaxed/simple; bh=edr9iy2A8cylz/h/xCNd3QjoCQ37pNqgk4oblataiws=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=OkMxhNfEYCm0l9ml8a5lhng4LGQXWE++NQvyHQdl6ZS/HjvDYblQMEXzFWuI/3Y1OyAeUgLfCPa+qK08zzVHUTrCwC6bLWM55Tb8mSkk7FpeDmYMW+OeRpdS1VRoJvurOyG/gCQYXyQnLvdTwIbS52C9AHEkXbDHc/agtO0s08M= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=OBQUYpup; arc=none smtp.client-ip=170.10.129.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="OBQUYpup" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1741891441; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=36Ck9jMgE/IDvdowq/TfUWiiXsumgSZZiybTXurn5AQ=; b=OBQUYpupJ6IP9AOEkInjsGt2z/cpiCApJld39m33B7PbzagSLv6CuyAXe8TcWr9VdcOLke v6pqgd7gnFRrpIzfW1a8sQnypwrkPqaynvnhhDCpySKG0Gl7OaxrMXxHtsL1aTUrAZ3zvg SlggKfhJDqTlmb7gjsQwpYQ9N1aaW5U= Received: from mx-prod-mc-02.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-393-zHLZrfbMMwugW1WfrT9SSw-1; Thu, 13 Mar 2025 14:43:59 -0400 X-MC-Unique: zHLZrfbMMwugW1WfrT9SSw-1 X-Mimecast-MFC-AGG-ID: zHLZrfbMMwugW1WfrT9SSw_1741891437 Received: from mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.4]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-02.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 7EA2D19560AB; Thu, 13 Mar 2025 18:43:57 +0000 (UTC) Received: from shalem.redhat.com (unknown [10.45.224.5]) by mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 9A205300376F; Thu, 13 Mar 2025 18:43:54 +0000 (UTC) From: Hans de Goede To: Sakari Ailus , Heimir Thor Sverrisson Cc: Hans de Goede , Stanislaw Gruszka , Ingvar Hagelund , Joachim Reichel , Bryan O'Donoghue , Hao Yao , Mauro Carvalho Chehab , linux-media@vger.kernel.org Subject: [PATCH v8 11/14] media: ov02c10: Switch to {enable,disable}_streams Date: Thu, 13 Mar 2025 19:43:11 +0100 Message-ID: <20250313184314.91410-12-hdegoede@redhat.com> In-Reply-To: <20250313184314.91410-1-hdegoede@redhat.com> References: <20250313184314.91410-1-hdegoede@redhat.com> Precedence: bulk X-Mailing-List: linux-media@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.4 Switch from s_stream() to enable_streams() and disable_streams() pad operations. They are preferred and required for streams support. Note this also stops calling ov02c10_stop_streaming() on enable_streams() errors. If ov02c10_start_streaming() fails OV02C10_REG_STREAM_CONTROL bit 0 will have never been set so there is no need to clear it on errors. Signed-off-by: Hans de Goede --- drivers/media/i2c/ov02c10.c | 59 +++++++++++++++++++++---------------- 1 file changed, 33 insertions(+), 26 deletions(-) diff --git a/drivers/media/i2c/ov02c10.c b/drivers/media/i2c/ov02c10.c index a46cacf301a2..da727e18a282 100644 --- a/drivers/media/i2c/ov02c10.c +++ b/drivers/media/i2c/ov02c10.c @@ -2,6 +2,7 @@ // Copyright (c) 2022 Intel Corporation. #include +#include #include #include #include @@ -602,41 +603,45 @@ static void ov02c10_stop_streaming(struct ov02c10 *ov02c10) cci_write(ov02c10->regmap, OV02C10_REG_STREAM_CONTROL, 0, NULL); } -static int ov02c10_set_stream(struct v4l2_subdev *sd, int enable) +static int ov02c10_enable_streams(struct v4l2_subdev *sd, + struct v4l2_subdev_state *state, + u32 pad, u64 streams_mask) { - struct ov02c10 *ov02c10 = to_ov02c10(sd); struct i2c_client *client = v4l2_get_subdevdata(sd); - int ret = 0; + struct ov02c10 *ov02c10 = to_ov02c10(sd); + int ret; - if (ov02c10->streaming == enable) - return 0; + guard(mutex)(&ov02c10->mutex); - mutex_lock(&ov02c10->mutex); - if (enable) { - ret = pm_runtime_get_sync(&client->dev); - if (ret < 0) { - pm_runtime_put_noidle(&client->dev); - mutex_unlock(&ov02c10->mutex); - return ret; - } + ret = pm_runtime_resume_and_get(&client->dev); + if (ret) + return ret; - ret = ov02c10_start_streaming(ov02c10); - if (ret) { - enable = 0; - ov02c10_stop_streaming(ov02c10); - pm_runtime_put(&client->dev); - } - } else { - ov02c10_stop_streaming(ov02c10); + ret = ov02c10_start_streaming(ov02c10); + if (ret == 0) + ov02c10->streaming = true; + else pm_runtime_put(&client->dev); - } - - ov02c10->streaming = enable; - mutex_unlock(&ov02c10->mutex); return ret; } +static int ov02c10_disable_streams(struct v4l2_subdev *sd, + struct v4l2_subdev_state *state, + u32 pad, u64 streams_mask) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct ov02c10 *ov02c10 = to_ov02c10(sd); + + guard(mutex)(&ov02c10->mutex); + + ov02c10_stop_streaming(ov02c10); + ov02c10->streaming = false; + pm_runtime_put(&client->dev); + + return 0; +} + /* This function tries to get power control resources */ static int ov02c10_get_pm_resources(struct device *dev) { @@ -836,7 +841,7 @@ static int ov02c10_init_state(struct v4l2_subdev *sd, } static const struct v4l2_subdev_video_ops ov02c10_video_ops = { - .s_stream = ov02c10_set_stream, + .s_stream = v4l2_subdev_s_stream_helper, }; static const struct v4l2_subdev_pad_ops ov02c10_pad_ops = { @@ -844,6 +849,8 @@ static const struct v4l2_subdev_pad_ops ov02c10_pad_ops = { .get_fmt = ov02c10_get_format, .enum_mbus_code = ov02c10_enum_mbus_code, .enum_frame_size = ov02c10_enum_frame_size, + .enable_streams = ov02c10_enable_streams, + .disable_streams = ov02c10_disable_streams, }; static const struct v4l2_subdev_ops ov02c10_subdev_ops = { From patchwork Thu Mar 13 18:43:12 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hans de Goede X-Patchwork-Id: 14015798 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id CE94E1DB54C for ; Thu, 13 Mar 2025 18:44:06 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741891448; cv=none; b=NLgCzh5IGFzvuwYcFCQSiap4SNRDu1xUDIbM5y6f8jihEcv6hBDcDs8AdMl8WWT2rSf+1CNQB0UdKxfDAHRKju9f8b81q10LeRYYtDbMWxnL4SmyveUwMAOF5ZGbpyJUWiqFhKXokVR4ttQV0ddHWW0ch0ZWP6u00Bz39NFQJTE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741891448; c=relaxed/simple; bh=XWTQrdQdiC78UysD6Ih5Rqa7iOi4/ORYBzSgZ9QUt2c=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=HuGGeOQ0mvwhhnFl6Y1XQPN/0K57ZqhkeWAnsc4ICzGO0XOp08u1hnnrJzcs9RkLyeKKcrkFGb0tmHo8skWBSS21leS1yM90NoSHRTg+wAbvicIF5DGozn6XYsTi73nb5XFIZMprMNp9NZ+ZczsgZhERPVFKxQoYz9cRcngSLgs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=NzEdtQTI; arc=none smtp.client-ip=170.10.133.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="NzEdtQTI" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1741891445; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=dyB8Mqumd9azPLY1PP1PR8hLAUSxfSze7YPjDN5OZkc=; b=NzEdtQTIBLDIfC/BR+TmJvQcH8dKHmoHKd6NulkZhXmNlM8KDB2WWz4EowiQh5wBsnoIfu xsMhd27Usxn/RCHmRezsJK+RhOJYUundqdoZWijSx46Hm/m/oaLB3cZEYnkL8P4Hokovml dyo9LvewhbrOukSH1/xGlvUir0BLmjE= Received: from mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-264-uzG_xOxxP1mzweEo8Gi8qg-1; Thu, 13 Mar 2025 14:44:02 -0400 X-MC-Unique: uzG_xOxxP1mzweEo8Gi8qg-1 X-Mimecast-MFC-AGG-ID: uzG_xOxxP1mzweEo8Gi8qg_1741891441 Received: from mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.4]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id D168718001FA; Thu, 13 Mar 2025 18:44:00 +0000 (UTC) Received: from shalem.redhat.com (unknown [10.45.224.5]) by mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id ED334300376F; Thu, 13 Mar 2025 18:43:57 +0000 (UTC) From: Hans de Goede To: Sakari Ailus , Heimir Thor Sverrisson Cc: Hans de Goede , Stanislaw Gruszka , Ingvar Hagelund , Joachim Reichel , Bryan O'Donoghue , Hao Yao , Mauro Carvalho Chehab , linux-media@vger.kernel.org Subject: [PATCH v8 12/14] media: ov02c10: Drop system suspend and resume handlers Date: Thu, 13 Mar 2025 19:43:12 +0100 Message-ID: <20250313184314.91410-13-hdegoede@redhat.com> In-Reply-To: <20250313184314.91410-1-hdegoede@redhat.com> References: <20250313184314.91410-1-hdegoede@redhat.com> Precedence: bulk X-Mailing-List: linux-media@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.4 Stopping streaming on a camera pipeline at system suspend time, and restarting it at system resume time, requires coordinated action between the bridge driver and the camera sensor driver. This is handled by the bridge driver calling the sensor's .s_stream() handler at system suspend and resume time. There is thus no need for the sensor to independently implement system sleep PM operations. Drop them. The streaming field of the driver's private structure is now unused, drop it as well. Signed-off-by: Hans de Goede --- drivers/media/i2c/ov02c10.c | 53 +++---------------------------------- 1 file changed, 4 insertions(+), 49 deletions(-) diff --git a/drivers/media/i2c/ov02c10.c b/drivers/media/i2c/ov02c10.c index da727e18a282..09e70ffcf07a 100644 --- a/drivers/media/i2c/ov02c10.c +++ b/drivers/media/i2c/ov02c10.c @@ -393,9 +393,6 @@ struct ov02c10 { /* MIPI lane info */ u32 link_freq_index; u8 mipi_lanes; - - /* Streaming on/off */ - bool streaming; }; static inline struct ov02c10 *to_ov02c10(struct v4l2_subdev *subdev) @@ -618,9 +615,7 @@ static int ov02c10_enable_streams(struct v4l2_subdev *sd, return ret; ret = ov02c10_start_streaming(ov02c10); - if (ret == 0) - ov02c10->streaming = true; - else + if (ret) pm_runtime_put(&client->dev); return ret; @@ -636,7 +631,6 @@ static int ov02c10_disable_streams(struct v4l2_subdev *sd, guard(mutex)(&ov02c10->mutex); ov02c10_stop_streaming(ov02c10); - ov02c10->streaming = false; pm_runtime_put(&client->dev); return 0; @@ -711,43 +705,6 @@ static int ov02c10_power_on(struct device *dev) return 0; } -static int __maybe_unused ov02c10_suspend(struct device *dev) -{ - struct i2c_client *client = to_i2c_client(dev); - struct v4l2_subdev *sd = i2c_get_clientdata(client); - struct ov02c10 *ov02c10 = to_ov02c10(sd); - - mutex_lock(&ov02c10->mutex); - if (ov02c10->streaming) - ov02c10_stop_streaming(ov02c10); - - mutex_unlock(&ov02c10->mutex); - - return 0; -} - -static int __maybe_unused ov02c10_resume(struct device *dev) -{ - struct i2c_client *client = to_i2c_client(dev); - struct v4l2_subdev *sd = i2c_get_clientdata(client); - struct ov02c10 *ov02c10 = to_ov02c10(sd); - int ret = 0; - - mutex_lock(&ov02c10->mutex); - if (!ov02c10->streaming) - goto exit; - - ret = ov02c10_start_streaming(ov02c10); - if (ret) { - ov02c10->streaming = false; - ov02c10_stop_streaming(ov02c10); - } - -exit: - mutex_unlock(&ov02c10->mutex); - return ret; -} - static int ov02c10_set_format(struct v4l2_subdev *sd, struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) @@ -1047,10 +1004,8 @@ static int ov02c10_probe(struct i2c_client *client) return ret; } -static const struct dev_pm_ops ov02c10_pm_ops = { - SET_SYSTEM_SLEEP_PM_OPS(ov02c10_suspend, ov02c10_resume) - SET_RUNTIME_PM_OPS(ov02c10_power_off, ov02c10_power_on, NULL) -}; +static DEFINE_RUNTIME_DEV_PM_OPS(ov02c10_pm_ops, ov02c10_power_off, + ov02c10_power_on, NULL); #ifdef CONFIG_ACPI static const struct acpi_device_id ov02c10_acpi_ids[] = { @@ -1064,7 +1019,7 @@ MODULE_DEVICE_TABLE(acpi, ov02c10_acpi_ids); static struct i2c_driver ov02c10_i2c_driver = { .driver = { .name = "ov02c10", - .pm = &ov02c10_pm_ops, + .pm = pm_sleep_ptr(&ov02c10_pm_ops), .acpi_match_table = ACPI_PTR(ov02c10_acpi_ids), }, .probe = ov02c10_probe, From patchwork Thu Mar 13 18:43:13 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hans de Goede X-Patchwork-Id: 14015799 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id DDD641DB54C for ; Thu, 13 Mar 2025 18:44:12 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741891454; cv=none; b=BU9prS9ItCF31wb5VD/bUcqaWt6vpKuZcuoRUlKoo29kOOgAE3t5It/h9fR3Gl49yvKk4zi1oldydgnWlfGbvp9qYVTRlqFWjjj2wstP0zHxAFRJ3PtdvMrBmBqC3vdy9pkgHNNpalws3uq+QD329G/1V9hw4IDTkzZrtdKeaKs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741891454; c=relaxed/simple; bh=Uk+so7eUmtvz2WjCluFzkpSqCe9MlbDfJkFZeJrws+A=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=nKSPb/WhEL8RZZu8tkeJ6RFnuZO1NDFFO32xjPnacwYwftGhkDYPmSnGqU8ky/Gq/gNMscnm0Pcn4CUdFKS/OM5WWi0oNzVUpfvey7ftc9E3CAiXFOP58mYRqlmZKrZmOkp7SMQkrSOtmPf3hhaVPZa8LoCGwgcWB75upf82SOg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=g0GiKz8F; arc=none smtp.client-ip=170.10.129.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="g0GiKz8F" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1741891451; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=GtnIs3r612IqfdsvGw8jSjrKvvgCjuMzj6IFiqbJk7Y=; b=g0GiKz8F7Yf+qQ3n+lF8Ib4kCue9I7qI9zn3aXsXYaxqPSvZoFsYO3QB1ehicQ9WkhH5g0 MwuWM0MNPRWvn1MOaXLe9b0XzO0Ml0+Dzqf1o//P4mbGC0yLR5KFvXSXVyPIAqSJ9mYOUu bnJjVXxrvN8qL4YTkACxvMI7UopL/KI= Received: from mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-255-rDgfnX4HPvaAkkEXWUhB3g-1; Thu, 13 Mar 2025 14:44:05 -0400 X-MC-Unique: rDgfnX4HPvaAkkEXWUhB3g-1 X-Mimecast-MFC-AGG-ID: rDgfnX4HPvaAkkEXWUhB3g_1741891444 Received: from mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.4]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 2D47F1800349; Thu, 13 Mar 2025 18:44:04 +0000 (UTC) Received: from shalem.redhat.com (unknown [10.45.224.5]) by mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 4B5B4300376F; Thu, 13 Mar 2025 18:44:01 +0000 (UTC) From: Hans de Goede To: Sakari Ailus , Heimir Thor Sverrisson Cc: Hans de Goede , Stanislaw Gruszka , Ingvar Hagelund , Joachim Reichel , Bryan O'Donoghue , Hao Yao , Mauro Carvalho Chehab , linux-media@vger.kernel.org Subject: [PATCH v8 13/14] media: ov02c10: Switch to using the sub-device state lock Date: Thu, 13 Mar 2025 19:43:13 +0100 Message-ID: <20250313184314.91410-14-hdegoede@redhat.com> In-Reply-To: <20250313184314.91410-1-hdegoede@redhat.com> References: <20250313184314.91410-1-hdegoede@redhat.com> Precedence: bulk X-Mailing-List: linux-media@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.4 Switch to using the sub-device state lock and properly call v4l2_subdev_init_finalize() / v4l2_subdev_cleanup() on probe() / remove(). While at it also properly setup runtime-pm before registering the subdev. Signed-off-by: Hans de Goede --- drivers/media/i2c/ov02c10.c | 51 +++++++++++++++++-------------------- 1 file changed, 23 insertions(+), 28 deletions(-) diff --git a/drivers/media/i2c/ov02c10.c b/drivers/media/i2c/ov02c10.c index 09e70ffcf07a..c559a69140ec 100644 --- a/drivers/media/i2c/ov02c10.c +++ b/drivers/media/i2c/ov02c10.c @@ -2,7 +2,6 @@ // Copyright (c) 2022 Intel Corporation. #include -#include #include #include #include @@ -387,9 +386,6 @@ struct ov02c10 { /* Current mode */ const struct ov02c10_mode *cur_mode; - /* To serialize asynchronous callbacks */ - struct mutex mutex; - /* MIPI lane info */ u32 link_freq_index; u8 mipi_lanes; @@ -490,7 +486,6 @@ static int ov02c10_init_controls(struct ov02c10 *ov02c10) if (ret) return ret; - ctrl_hdlr->lock = &ov02c10->mutex; cur_mode = ov02c10->cur_mode; ov02c10->link_freq = v4l2_ctrl_new_int_menu(ctrl_hdlr, @@ -608,8 +603,6 @@ static int ov02c10_enable_streams(struct v4l2_subdev *sd, struct ov02c10 *ov02c10 = to_ov02c10(sd); int ret; - guard(mutex)(&ov02c10->mutex); - ret = pm_runtime_resume_and_get(&client->dev); if (ret) return ret; @@ -628,8 +621,6 @@ static int ov02c10_disable_streams(struct v4l2_subdev *sd, struct i2c_client *client = v4l2_get_subdevdata(sd); struct ov02c10 *ov02c10 = to_ov02c10(sd); - guard(mutex)(&ov02c10->mutex); - ov02c10_stop_streaming(ov02c10); pm_runtime_put(&client->dev); @@ -718,7 +709,6 @@ static int ov02c10_set_format(struct v4l2_subdev *sd, height, fmt->format.width, fmt->format.height); - mutex_lock(&ov02c10->mutex); ov02c10_update_pad_format(mode, &fmt->format); if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { *v4l2_subdev_state_get_format(sd_state, fmt->pad) = fmt->format; @@ -736,7 +726,6 @@ static int ov02c10_set_format(struct v4l2_subdev *sd, __v4l2_ctrl_modify_range(ov02c10->hblank, h_blank, h_blank, 1, h_blank); } - mutex_unlock(&ov02c10->mutex); return 0; } @@ -747,14 +736,11 @@ static int ov02c10_get_format(struct v4l2_subdev *sd, { struct ov02c10 *ov02c10 = to_ov02c10(sd); - mutex_lock(&ov02c10->mutex); if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) fmt->format = *v4l2_subdev_state_get_format(sd_state, fmt->pad); else ov02c10_update_pad_format(ov02c10->cur_mode, &fmt->format); - mutex_unlock(&ov02c10->mutex); - return 0; } @@ -909,13 +895,16 @@ static int ov02c10_check_hwcfg(struct device *dev, struct ov02c10 *ov02c10) static void ov02c10_remove(struct i2c_client *client) { struct v4l2_subdev *sd = i2c_get_clientdata(client); - struct ov02c10 *ov02c10 = to_ov02c10(sd); v4l2_async_unregister_subdev(sd); + v4l2_subdev_cleanup(sd); media_entity_cleanup(&sd->entity); v4l2_ctrl_handler_free(sd->ctrl_handler); pm_runtime_disable(&client->dev); - mutex_destroy(&ov02c10->mutex); + if (!pm_runtime_status_suspended(&client->dev)) { + ov02c10_power_off(&client->dev); + pm_runtime_set_suspended(&client->dev); + } } static int ov02c10_probe(struct i2c_client *client) @@ -951,10 +940,9 @@ static int ov02c10_probe(struct i2c_client *client) ret = ov02c10_identify_module(ov02c10); if (ret) { dev_err(&client->dev, "failed to find sensor: %d", ret); - goto probe_error_ret; + goto probe_error_power_off; } - mutex_init(&ov02c10->mutex); ov02c10->cur_mode = &supported_modes[0]; ret = ov02c10_init_controls(ov02c10); @@ -974,31 +962,38 @@ static int ov02c10_probe(struct i2c_client *client) goto probe_error_v4l2_ctrl_handler_free; } + ov02c10->sd.state_lock = ov02c10->ctrl_handler.lock; + ret = v4l2_subdev_init_finalize(&ov02c10->sd); + if (ret < 0) { + dev_err(&client->dev, "failed to init subdev: %d", ret); + goto probe_error_media_entity_cleanup; + } + + pm_runtime_set_active(&client->dev); + pm_runtime_enable(&client->dev); + ret = v4l2_async_register_subdev_sensor(&ov02c10->sd); if (ret < 0) { dev_err(&client->dev, "failed to register V4L2 subdev: %d", ret); - goto probe_error_media_entity_cleanup; + goto probe_error_v4l2_subdev_cleanup; } - /* - * Device is already turned on by i2c-core with ACPI domain PM. - * Enable runtime PM and turn off the device. - */ - pm_runtime_set_active(&client->dev); - pm_runtime_enable(&client->dev); pm_runtime_idle(&client->dev); - return 0; +probe_error_v4l2_subdev_cleanup: + pm_runtime_disable(&client->dev); + pm_runtime_set_suspended(&client->dev); + v4l2_subdev_cleanup(&ov02c10->sd); + probe_error_media_entity_cleanup: media_entity_cleanup(&ov02c10->sd.entity); probe_error_v4l2_ctrl_handler_free: v4l2_ctrl_handler_free(ov02c10->sd.ctrl_handler); - mutex_destroy(&ov02c10->mutex); -probe_error_ret: +probe_error_power_off: ov02c10_power_off(&client->dev); return ret; From patchwork Thu Mar 13 18:43:14 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hans de Goede X-Patchwork-Id: 14015800 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id F25001DB54C for ; Thu, 13 Mar 2025 18:44:15 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741891457; cv=none; b=DRhPyzoyLOyGqvhITyH7TanmwOdlwiO/QnkYTX2puMEFoXep6GZ6aTC4fw+luejBeqafT91DGCwsr92e71Sct6sQEUDRRqwQWMfOc3gWevHn/FJgqDOHBBYMSr/Kzpjf794cC99QDOkWSUAZdqTFy+Ecl9m4oED9X+xb6nC6eeM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741891457; c=relaxed/simple; bh=4tvMhb6q6CdLQ8UKLamsrBJYdNROiCjOz8/xB3td5MI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=I3TewEz2Odu551SW8effzQ3klo05FzTKWFoXbmEvhBlFWhjn0mXoitLl5JSmCkeAUoh7jhCYKGCUQ9KBy0GyjIenj/WsKPDnwWDNsDxBvCaRji/T3unC3ZVl5UZdRMWU3WzzjO1p100cOCS0BYJdcJKOG2dOguqsNqRACAsiAZA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=CHNEkFBH; arc=none smtp.client-ip=170.10.129.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="CHNEkFBH" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1741891454; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Gtgjw51An2Qs6UfXdq/PlrAgwddsI3CBCPfkD4p9e/Q=; b=CHNEkFBH8iiaHn6kP5BekirKWT1amHH/KRPvL8y8KHHNUBX5vFZt5DmYwR5nVjWDOWhRHj Z2kqsO0Fuk0WUVVxhWKSRVl+AgVCIXUSmC5OBmxhBdebo/95C4HXzCS07hqA4pi9BapdGp GaRaGVJhwJyjTTbigoy2FCH3hT3rREs= Received: from mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-77-50MLQUuXOKaLNaT87mDtVA-1; Thu, 13 Mar 2025 14:44:09 -0400 X-MC-Unique: 50MLQUuXOKaLNaT87mDtVA-1 X-Mimecast-MFC-AGG-ID: 50MLQUuXOKaLNaT87mDtVA_1741891447 Received: from mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.4]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 8D50E19560B7; Thu, 13 Mar 2025 18:44:07 +0000 (UTC) Received: from shalem.redhat.com (unknown [10.45.224.5]) by mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 9C70E300376F; Thu, 13 Mar 2025 18:44:04 +0000 (UTC) From: Hans de Goede To: Sakari Ailus , Heimir Thor Sverrisson Cc: Hans de Goede , Stanislaw Gruszka , Ingvar Hagelund , Joachim Reichel , Bryan O'Donoghue , Hao Yao , Mauro Carvalho Chehab , linux-media@vger.kernel.org Subject: [PATCH v8 14/14] media: ov02c10: Use v4l2_subdev_get_fmt() as v4l2_subdev_pad_ops.get_fmt() Date: Thu, 13 Mar 2025 19:43:14 +0100 Message-ID: <20250313184314.91410-15-hdegoede@redhat.com> In-Reply-To: <20250313184314.91410-1-hdegoede@redhat.com> References: <20250313184314.91410-1-hdegoede@redhat.com> Precedence: bulk X-Mailing-List: linux-media@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.4 Store current-mode format in active-state format on non try set_format() calls and use v4l2_subdev_get_fmt() as v4l2_subdev_pad_ops.get_fmt(). Signed-off-by: Hans de Goede --- drivers/media/i2c/ov02c10.c | 42 ++++++++++++------------------------- 1 file changed, 13 insertions(+), 29 deletions(-) diff --git a/drivers/media/i2c/ov02c10.c b/drivers/media/i2c/ov02c10.c index c559a69140ec..5626aa2fe62c 100644 --- a/drivers/media/i2c/ov02c10.c +++ b/drivers/media/i2c/ov02c10.c @@ -710,36 +710,20 @@ static int ov02c10_set_format(struct v4l2_subdev *sd, fmt->format.height); ov02c10_update_pad_format(mode, &fmt->format); - if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { - *v4l2_subdev_state_get_format(sd_state, fmt->pad) = fmt->format; - } else { - ov02c10->cur_mode = mode; - - /* Update limits and set FPS to default */ - vblank_def = mode->vts_min * ov02c10->mipi_lanes - mode->height; - __v4l2_ctrl_modify_range(ov02c10->vblank, - mode->vts_min - mode->height, - OV02C10_VTS_MAX - mode->height, 1, - vblank_def); - __v4l2_ctrl_s_ctrl(ov02c10->vblank, vblank_def); - h_blank = mode->hts - mode->width; - __v4l2_ctrl_modify_range(ov02c10->hblank, h_blank, h_blank, 1, - h_blank); - } - - return 0; -} - -static int ov02c10_get_format(struct v4l2_subdev *sd, - struct v4l2_subdev_state *sd_state, - struct v4l2_subdev_format *fmt) -{ - struct ov02c10 *ov02c10 = to_ov02c10(sd); + *v4l2_subdev_state_get_format(sd_state, fmt->pad) = fmt->format; if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) - fmt->format = *v4l2_subdev_state_get_format(sd_state, fmt->pad); - else - ov02c10_update_pad_format(ov02c10->cur_mode, &fmt->format); + return 0; + + ov02c10->cur_mode = mode; + + /* Update limits and set FPS to default */ + vblank_def = mode->vts_min * ov02c10->mipi_lanes - mode->height; + __v4l2_ctrl_modify_range(ov02c10->vblank, mode->vts_min - mode->height, + OV02C10_VTS_MAX - mode->height, 1, vblank_def); + __v4l2_ctrl_s_ctrl(ov02c10->vblank, vblank_def); + h_blank = mode->hts - mode->width; + __v4l2_ctrl_modify_range(ov02c10->hblank, h_blank, h_blank, 1, h_blank); return 0; } @@ -789,7 +773,7 @@ static const struct v4l2_subdev_video_ops ov02c10_video_ops = { static const struct v4l2_subdev_pad_ops ov02c10_pad_ops = { .set_fmt = ov02c10_set_format, - .get_fmt = ov02c10_get_format, + .get_fmt = v4l2_subdev_get_fmt, .enum_mbus_code = ov02c10_enum_mbus_code, .enum_frame_size = ov02c10_enum_frame_size, .enable_streams = ov02c10_enable_streams,