From nobody Mon Sep 28 04:55:37 2026 Received: from mail-ed1-f46.google.com (mail-ed1-f46.google.com [209.85.208.46]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C4AB940C5AE for ; Wed, 26 Aug 2026 13:23:08 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.208.46 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787750591; cv=none; b=GtJvWzGO2z0fHUzOKOf4+irwQ9wW3xeUNXdtKByM/Qo91ieMBBvr2ch+j8Wk8tt/qFdnbl7eUXToCm6odGT8Rk9ImHIfi2LBSX/DU47zJF991A5exo74Buw7FWTXiY6JKw/7QWxwcN7S56g0Ph9OBUdoTpdtOQr2VpZmqH4wVfA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787750591; c=relaxed/simple; bh=ERoCNTZ/CHn8B9pukzOen5JWEiK+GdKUOJzwBwFx7QU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=iXd5Kedao7GJnSdchFTwduUV6wWFCf+pbPGepiGKU1L6It9PgiPNufjVykUqoOH5RUNVs2ZNa//Y4Lgjz8w+/fEZqTEYxlnAB+pUrOzplZxcje8D3NoGoSezlE9BEo5z6vgq70RaA20xVghVgycI3Odul9fO7H8qLvOsdcDpI+E= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=PfilKAnl; arc=none smtp.client-ip=209.85.208.46 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="PfilKAnl" Received: by mail-ed1-f46.google.com with SMTP id 4fb4d7f45d1cf-6a422090b2fso1312268a12.0 for ; Wed, 26 Aug 2026 06:23:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1787750587; x=1788355387; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=IG3JNu73SFfzEruBErjSVJbPbEEwmrekUywQqhuxvaw=; b=PfilKAnlW9Alb8vi8kIfkR5TQPGToKXR9QMtdQwsgMdDoKrInEoWorlF51hT5Tim2N 2ygSuhsIe9RkpuB2t6H3pg1sKSUkSF891xUUytqMLBFYhlU+QzAv3m5Rs8fb3rjbIZ29 FyZ/PW775PzUv5wY5PSKjUTW1vSpdm9fM8ICAsPPFhugQ7kAALP6h8tsSoUKE6DY5J+J VnCF+PtdBfuX73gmyYeUgrw7qVWn6sGm6EkvcoioPYJFky35o7FCNNitMrAmKB7St/jY eE021GEMBDJWVYl8W2sRwpF5ummuta9kgqBxGM+wGdNKDGbFDnPCEA1eGK0KdSuLvGS9 /pFg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1787750587; x=1788355387; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=IG3JNu73SFfzEruBErjSVJbPbEEwmrekUywQqhuxvaw=; b=lUX0lEIN/CGwON+pmH2fV3sEnHbyRNkuKDPXj7vj6I6M3Vtk93TtEdJ2UY2cgElFYf a4ZJMLgUMtQP/QrtkOcMs4FA1UH5poSDW4g5Wlck4OtV4EPYYZ1J0+rNkC7EzNl3sYWE 7rYo3SMtqAsPFDCouyYPgnCXbwQ0YHnM3ZioTuAx6ox4QCX7yO4Lhuo3bXEXrqhVpgRm KCcidVwOsXxSpBpzwpts9sPbaQDfUvFUrMr/pZa1lgjfd+bceJ0WVeGINPL+wR8Fh3w2 zlttOtU71jM5szPXYKRASA1Cs7Y98o1PKZJs9mQmegNp2uacXNxIs15TGlIhZrA1dlwX 3X7g== X-Forwarded-Encrypted: i=1; AHgh+RqFF1Gl1Brx1K7uwQqqZpH9JXOVZBqVA+yMf7x9tjYjvJ0mek5JyG/YC/7Q0RGnsm40uDFseV0sN/6/ofo=@vger.kernel.org X-Gm-Message-State: AFuF++mQWlZw5HdttRD+xS0cHIikiqgLlk+ffj16Tg9xl0d3zgB5yQzX r38baPNA6zx5Tk/wcb1KI4xHEO3sGbZjmaBjI95JS1TpyGhp08rQIsY1 X-Gm-Gg: AR+sD12ZaSU+iPRsXK+yvnTjn3ZUXbRzhVAsq8/tsHAx19xWF3I6OdoR2MLAQwrSvm1 0RUoMnRetXhocl5tXb1mn/E1js9E8G1t0NNF5BJz7Hr3A/MtxuedaLyimh5WMHw+TdI1/au+cAr cf6qQCD9HbeX5Iv+a1BUkMcl/4yLlSUQIVTXhLoQNO3GSJ1bTQvQpwidlkWK7iiVLhc8AfLp4SM 0kdVM4B0KZBqGEzDonqTd5PSyAg5eHpdlYxKv5PVwxKUtg1kl9imCK4MQCYeJiOSelOxbs+IdRd sYyAK/HP1iodXUc2Tk0RxY31N4FIKcoupLmT4b3fKm8P9FuNaIk8Nahbfe7OW+SH5CgnUEEvYVl 43Yz1/FQH/8O1PBROD345Ui+0x2EUxFN87Kb29XWiJW7W5qZl/iGQxiiJqTurLFsb8zzLuwkCeN 0cpvJnS6+IQLpeduWCWZjuY6ljfNj3sdIynVz0iB4OAy1c283I7XypVQP0hp5q9wp+U7oMKZF6I iJSme3Nk+RUnirUHlPcg7rfcDHN/RN+7YSLAlHfu4A= X-Received: by 2002:a05:6402:4285:b0:698:5610:76e5 with SMTP id 4fb4d7f45d1cf-6a5df5cae52mr11531030a12.6.1787750586429; Wed, 26 Aug 2026 06:23:06 -0700 (PDT) Received: from 1Z10 ([37.163.238.51]) by smtp.gmail.com with ESMTPSA id 4fb4d7f45d1cf-6a5dea83a30sm3633147a12.15.2026.08.26.06.23.03 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 26 Aug 2026 06:23:05 -0700 (PDT) From: Maurizio Casciano To: linux-media@vger.kernel.org Cc: Mauro Carvalho Chehab , Sakari Ailus , Bingbu Cao , Jacopo Mondi , Nicholas Roth , Andy Shevchenko , Hans de Goede , Greg Kroah-Hartman , Jose Maria Martin , linux-staging@lists.linux.dev, linux-kernel@vger.kernel.org, Maurizio Casciano Subject: [PATCH 1/8] media: ov8858: support 19.2 MHz clock and CHT gain setup Date: Wed, 26 Aug 2026 15:22:49 +0200 Message-ID: <20260826132256.3343451-2-mauriziocasciano7@gmail.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260826132256.3343451-1-mauriziocasciano7@gmail.com> References: <20260826132256.3343451-1-mauriziocasciano7@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The Yoga Book drives its OV8858 from a 19.2 MHz platform clock, while the existing mode tables program the sensor PLL for 24 MHz. Reusing those settings produces incorrect internal and CSI-2 clocks. Accept both input rates and use the actual rate for the reset delay. For 19.2 MHz, apply the Cherry Trail MRD PLL and black-level settings after the generic mode table. The 19.2 MHz platform uses the per-channel manual white-balance registers for digital gain. Program registers 0x5032, 0x5034 and 0x5036 and expose their 1x-to-4x range, while retaining the existing long-exposure gain block for 24 MHz systems. The manual white-balance register definitions and programming follow the GPL-2.0 Intel OV5670 driver, so retain its 2017 Intel copyright notice in this file. No proprietary source or tuning binary is included. Tested on the Lenovo Yoga Book YB1-X91L OV8858 with full-range test bars and real 10-bit Bayer frames. Signed-off-by: Maurizio Casciano Assisted-by: Codex:gpt-5.6-sol sparse --- drivers/media/i2c/ov8858.c | 126 ++++++++++++++++++++++++++++++------- 1 file changed, 103 insertions(+), 23 deletions(-) diff --git a/drivers/media/i2c/ov8858.c b/drivers/media/i2c/ov8858.c index 3f45f7fab833..f2bed3e88382 100644 --- a/drivers/media/i2c/ov8858.c +++ b/drivers/media/i2c/ov8858.c @@ -3,10 +3,9 @@ * Copyright (C) 2023 Jacopo Mondi * Copyright (C) 2022 Nicholas Roth * Copyright (C) 2017 Fuzhou Rockchip Electronics Co., Ltd. + * Copyright (c) 2017 Intel Corporation. */ =20 -#include - #include #include #include @@ -18,6 +17,7 @@ #include #include #include +#include =20 #include #include @@ -29,7 +29,8 @@ #include =20 #define OV8858_LINK_FREQ 360000000U -#define OV8858_XVCLK_FREQ 24000000 +#define OV8858_XVCLK_FREQ_19_2MHZ 19200000 +#define OV8858_XVCLK_FREQ_24MHZ 24000000 =20 #define OV8858_REG_SIZE_SHIFT 16 #define OV8858_REG_ADDR_MASK 0xffff @@ -59,15 +60,23 @@ #define OV8858_LONG_GAIN_STEP 1 #define OV8858_LONG_GAIN_DEFAULT 0x80 =20 +#define OV8858_REG_MWB_RED_GAIN OV8858_REG_16BIT(0x5032) +#define OV8858_REG_MWB_GREEN_GAIN OV8858_REG_16BIT(0x5034) +#define OV8858_REG_MWB_BLUE_GAIN OV8858_REG_16BIT(0x5036) +#define OV8858_MWB_GAIN_MIN 0x400 +#define OV8858_MWB_GAIN_MAX 0xfff +#define OV8858_MWB_GAIN_DEFAULT 0x400 + #define OV8858_REG_LONG_DIGIGAIN OV8858_REG_16BIT(0x350a) #define OV8858_LONG_DIGIGAIN_H_MASK 0x3fc0 #define OV8858_LONG_DIGIGAIN_L_MASK 0x3f #define OV8858_LONG_DIGIGAIN_H_SHIFT 2 #define OV8858_LONG_DIGIGAIN_MIN 0x0 #define OV8858_LONG_DIGIGAIN_MAX 0x3fff -#define OV8858_LONG_DIGIGAIN_STEP 1 #define OV8858_LONG_DIGIGAIN_DEFAULT 0x200 =20 +#define OV8858_DIGITAL_GAIN_STEP 1 + #define OV8858_REG_VTS OV8858_REG_16BIT(0x380e) #define OV8858_VTS_MAX 0x7fff =20 @@ -104,6 +113,7 @@ struct ov8858_mode { =20 struct ov8858 { struct clk *xvclk; + unsigned long xvclk_rate; struct gpio_desc *reset_gpio; struct gpio_desc *pwdn_gpio; struct regulator_bulk_data supplies[ARRAY_SIZE(ov8858_supply_names)]; @@ -121,6 +131,41 @@ struct ov8858 { unsigned int num_lanes; }; =20 +/* + * Cherry Trail MRD production settings for a 19.2 MHz input and 360 MHz + * CSI-2 link. Apply these after the otherwise reusable 24 MHz mode table. + * + * Besides the corrected sensor/MIPI PLL divisors, keep the final common + * black-level settings here. The per-mode tables retain their resolution + * dependent black-column anchors and window sizes. + */ +static const struct regval ov8858_cht_mrd_19_2mhz[] =3D { + {0x0300, 0x00}, + {0x0302, 0x27}, + {0x0303, 0x00}, + {0x0304, 0x03}, + {0x030b, 0x00}, + {0x030d, 0x27}, + {0x030e, 0x00}, + {0x030f, 0x04}, + {0x0312, 0x01}, + {0x031e, 0x0c}, + {0x3f08, 0x08}, + {0x400a, 0x01}, + {0x400d, 0x10}, + {0x4011, 0x20}, + {0x403e, 0x08}, + {0x4040, 0x07}, + {0x4041, 0xc6}, + {0x4202, 0x00}, + {0x4500, 0x58}, + {0x470b, 0x28}, + {0x4837, 0x15}, + {0x58f4, 0x32}, + {0x58f8, 0x3d}, + {REG_NULL, 0x00}, +}; + static inline struct ov8858 *sd_to_ov8858(struct v4l2_subdev *sd) { return container_of(sd, struct ov8858, subdev); @@ -1345,6 +1390,14 @@ static int ov8858_start_stream(struct ov8858 *ov8858, if (ret) return ret; =20 + /* The mode tables contain PLL settings for a 24 MHz input clock. */ + if (ov8858->xvclk_rate =3D=3D OV8858_XVCLK_FREQ_19_2MHZ) { + ret =3D ov8858_write_array(ov8858, + ov8858_cht_mrd_19_2mhz); + if (ret) + return ret; + } + /* 200 usec max to let PLL stabilize. */ fsleep(200); =20 @@ -1523,6 +1576,31 @@ static int ov8858_enable_test_pattern(struct ov8858 = *ov8858, u32 pattern) return ov8858_write(ov8858, OV8858_REG_TEST_PATTERN, val, NULL); } =20 +static int ov8858_set_digital_gain(struct ov8858 *ov8858, u32 gain) +{ + u16 long_gain; + int ret; + + if (ov8858->xvclk_rate !=3D OV8858_XVCLK_FREQ_19_2MHZ) { + long_gain =3D (gain & OV8858_LONG_DIGIGAIN_L_MASK) | + ((gain & OV8858_LONG_DIGIGAIN_H_MASK) << + OV8858_LONG_DIGIGAIN_H_SHIFT); + + return ov8858_write(ov8858, OV8858_REG_LONG_DIGIGAIN, + long_gain, NULL); + } + + ret =3D ov8858_write(ov8858, OV8858_REG_MWB_RED_GAIN, gain, NULL); + if (ret) + return ret; + + ret =3D ov8858_write(ov8858, OV8858_REG_MWB_GREEN_GAIN, gain, NULL); + if (ret) + return ret; + + return ov8858_write(ov8858, OV8858_REG_MWB_BLUE_GAIN, gain, NULL); +} + static int ov8858_set_ctrl(struct v4l2_ctrl *ctrl) { struct ov8858 *ov8858 =3D container_of(ctrl->handler, @@ -1531,7 +1609,6 @@ static int ov8858_set_ctrl(struct v4l2_ctrl *ctrl) struct i2c_client *client =3D v4l2_get_subdevdata(&ov8858->subdev); struct v4l2_mbus_framefmt *format; struct v4l2_subdev_state *state; - u16 digi_gain; s64 max_exp; int ret; =20 @@ -1570,17 +1647,7 @@ static int ov8858_set_ctrl(struct v4l2_ctrl *ctrl) ctrl->val, NULL); break; case V4L2_CID_DIGITAL_GAIN: - /* - * Digital gain is assembled as: - * 0x350a[7:0] =3D dgain[13:6] - * 0x350b[5:0] =3D dgain[5:0] - * Reassemble the control value to write it in one go. - */ - digi_gain =3D (ctrl->val & OV8858_LONG_DIGIGAIN_L_MASK) - | ((ctrl->val & OV8858_LONG_DIGIGAIN_H_MASK) << - OV8858_LONG_DIGIGAIN_H_SHIFT); - ret =3D ov8858_write(ov8858, OV8858_REG_LONG_DIGIGAIN, - digi_gain, NULL); + ret =3D ov8858_set_digital_gain(ov8858, ctrl->val); break; case V4L2_CID_VBLANK: ret =3D ov8858_write(ov8858, OV8858_REG_VTS, @@ -1616,9 +1683,6 @@ static int ov8858_power_on(struct ov8858 *ov8858) unsigned long delay_us; int ret; =20 - if (clk_get_rate(ov8858->xvclk) !=3D OV8858_XVCLK_FREQ) - dev_warn(dev, "xvclk mismatched, modes are based on 24MHz\n"); - ret =3D clk_prepare_enable(ov8858->xvclk); if (ret < 0) { dev_err(dev, "Failed to enable xvclk\n"); @@ -1637,7 +1701,7 @@ static int ov8858_power_on(struct ov8858 *ov8858) * transaction, but a double sleep between the release of gpios * helps with sporadic failures observed at probe time. */ - delay_us =3D DIV_ROUND_UP(8192, OV8858_XVCLK_FREQ / 1000 / 1000); + delay_us =3D DIV_ROUND_UP(8192, ov8858->xvclk_rate / 1000 / 1000); =20 gpiod_set_value_cansleep(ov8858->reset_gpio, 0); fsleep(delay_us); @@ -1697,6 +1761,9 @@ static int ov8858_init_ctrls(struct ov8858 *ov8858) struct v4l2_ctrl_handler *handler =3D &ov8858->ctrl_handler; const struct ov8858_mode *mode =3D &ov8858_modes[0]; struct v4l2_fwnode_device_properties props; + u32 digital_gain_default =3D OV8858_LONG_DIGIGAIN_DEFAULT; + u32 digital_gain_max =3D OV8858_LONG_DIGIGAIN_MAX; + u32 digital_gain_min =3D OV8858_LONG_DIGIGAIN_MIN; s64 exposure_max, vblank_def; unsigned int pixel_rate; struct v4l2_ctrl *ctrl; @@ -1740,10 +1807,16 @@ static int ov8858_init_ctrls(struct ov8858 *ov8858) OV8858_LONG_GAIN_MIN, OV8858_LONG_GAIN_MAX, OV8858_LONG_GAIN_STEP, OV8858_LONG_GAIN_DEFAULT); =20 + if (ov8858->xvclk_rate =3D=3D OV8858_XVCLK_FREQ_19_2MHZ) { + digital_gain_min =3D OV8858_MWB_GAIN_MIN; + digital_gain_max =3D OV8858_MWB_GAIN_MAX; + digital_gain_default =3D OV8858_MWB_GAIN_DEFAULT; + } + v4l2_ctrl_new_std(handler, &ov8858_ctrl_ops, V4L2_CID_DIGITAL_GAIN, - OV8858_LONG_DIGIGAIN_MIN, OV8858_LONG_DIGIGAIN_MAX, - OV8858_LONG_DIGIGAIN_STEP, - OV8858_LONG_DIGIGAIN_DEFAULT); + digital_gain_min, digital_gain_max, + OV8858_DIGITAL_GAIN_STEP, + digital_gain_default); =20 v4l2_ctrl_new_std_menu_items(handler, &ov8858_ctrl_ops, V4L2_CID_TEST_PATTERN, @@ -1881,6 +1954,13 @@ static int ov8858_probe(struct i2c_client *client) return dev_err_probe(dev, PTR_ERR(ov8858->xvclk), "Failed to get xvclk\n"); =20 + ov8858->xvclk_rate =3D clk_get_rate(ov8858->xvclk); + if (ov8858->xvclk_rate !=3D OV8858_XVCLK_FREQ_19_2MHZ && + ov8858->xvclk_rate !=3D OV8858_XVCLK_FREQ_24MHZ) + return dev_err_probe(dev, -EINVAL, + "Unsupported xvclk rate %lu Hz\n", + ov8858->xvclk_rate); + ov8858->reset_gpio =3D devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH); if (IS_ERR(ov8858->reset_gpio)) --=20 2.53.0 From nobody Mon Sep 28 04:55:37 2026 Received: from mail-ej1-f52.google.com (mail-ej1-f52.google.com [209.85.218.52]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 606B1421259 for ; Wed, 26 Aug 2026 13:23:10 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.218.52 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787750591; cv=none; b=e/oasjtrJ7zR+IIGT2Cc7BL0W5pv1wQXHkif0GyrGXR5FoWjwH8BlK0LdcozNWzobmCdlcfa6Evzm7G4Xqc8J+2Wc5BLKOv4UnC2l27dF9NCCq65bbDFv5eA7mU5BobtWL8gXSSK1Ffy33e9fZLT4W9HMSJLdGOdqZWmFFsElnQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787750591; c=relaxed/simple; bh=Oi/dCIRA/+pshEFx53wMZKN+XEMFr0GqM+M0K4ABDm8=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=eWw4w4jvTqF9TzaQgAq7aXpAccyoi9s3qEzpWCz7DxXLg4NroW9OY+tmDjsOSwaQC47ikKzLkJ5dxJbz5OvgFYPPlJe4vYuHRYrh18wuPZSGrOCqXj/eqWyT8wVHf8u+49nw1+WHDL7hUFtIhTMuGISgLS/6l2y5sqwIME/M6q8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=EKgtHnh0; arc=none smtp.client-ip=209.85.218.52 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="EKgtHnh0" Received: by mail-ej1-f52.google.com with SMTP id a640c23a62f3a-c197e7e4e94so139886666b.2 for ; Wed, 26 Aug 2026 06:23:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1787750588; x=1788355388; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=VMc5Fvp4Rfyxekd9+9mnrTAhpeQULh9Pwl9GwGfns1I=; b=EKgtHnh0BVhJ+oMPaqbtHQzAmzK1O8H7bvBh1TdU4ttKkr74v0zRxQ3RZ8hSEhEByE 6O3EK1uSa9K3n/r7+cYfOrcAcgxw2/N7URAZdWz5UJiTlUf/8kjzm6KpUPd40R0gOl3v q0Ig1jtvUHvGqoEB38c57S5LaOEcG6MwSWXJB6XTtPNCbZVLbkbbY9+uLyTEtnsw1JK3 7Fgpu9La3m0GE2i5ip+FbVJFdh58TzuDEJIq8mv06OOAgy6nrnm2RoyM5uKESvyapFy2 GYvZbHM0wzbh9Ok52CYoqOTO1fzajVtfKX9M7/pSDospMGxacZV1IpRcjlQKs5pekZuS u1LQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1787750588; x=1788355388; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=VMc5Fvp4Rfyxekd9+9mnrTAhpeQULh9Pwl9GwGfns1I=; b=DoXWrQn32+XcloS6g9VoyLfEoDVk5FrPodvo5E3sJMQcOGF0pszN0CeJp1ltRkiCSV dOsdFsR3RmJ+td8DX7ans+tyV6ADXRLXkC3HFMcv7f0f9rRVnpl/FJElouChpVsivbKy hfuP0VAhdy7YRQvdlwuJmRSVT8yIEIHRlV72ZUfS5KPNFEgjlwhalaedEC4y4ul4bWQC kyEeYey5Z6Zy6HQSV15PH2vh1Dm3iO8DGX9VGMiQHeZHVPzs+6p4SkxwCVrZGCehfhj/ 0d4Dx/20zpDfwSvlI7KIj3a1p5Sm5uUeiy/6qn+LOTc/FNDlrFhXmJgEAbWjEKoCTeM/ qSKA== X-Forwarded-Encrypted: i=1; AHgh+Rp9ckeP7c+JnqWU2isz1GB0njssFHNO2G7O3aDXNvEBTsMf9ecfGigdp6fZXk58iOFbQvJLWrRf/5Mh230=@vger.kernel.org X-Gm-Message-State: AFuF++km+rFkum5fcRXacRzsDOV5YUYxhAgs4MI2j6PZr8sV7u8fZ448 7C9FPyTo0RwC/49v3148RpqZyI+hq0FuYqcoAVh9AHQoTV90cLOzBtgE X-Gm-Gg: AR+sD10AyvnDlxVbHD6S0s9bk6WfXSysgMxodynIdSuSBViHtQ6fNhbLZyexP1787UO TYCFBRnaZkBUcWAJ9ES1n0tM29jNky/wu5f0/PJ6caQktM6FcHBCcA/bJWQ84UE15Rx/a+oqfNp 0hx75DlR5yxTmhb9d0IGhSY5beoJjgEPjpz64PS0SWn4eGxLAnwut+tBs8Q5+MRqVlxLML104Wh MqCGgH+6qnvgSGE3tnJl3dXbUq+MZ+LTIbiMzR9lidGmUTPz2j9NgqKTPSfqE8h0+mcts+sMK+V fthzJTvlGYRXvGfVsZzg6EVHzlhGnazOuZqE1X6LknId4qp2eM5JtzMo/2Fr4jlCyYMwDrTcRlH NzFo+ybrmF9ejJmdyn4crzRoeQt8o5ILP7PGzvHAt9jJVqojQHlF+LtdKAAQ4QZbYsHyRitTCjO E8bPq7R6by3hn7ef35K8Hwy2VjHvMCKSdTJhcaQEuDQzerPi3C8RQ57bsT1S6FW7Du4UiQNF8JE vEAHRuzgWceNMeeTV5+rQ1M3DFPdWLKZiSurNhJV+c= X-Received: by 2002:a17:907:6088:b0:c21:35d0:f435 with SMTP id a640c23a62f3a-c250bc0f8f0mr856005166b.10.1787750588312; Wed, 26 Aug 2026 06:23:08 -0700 (PDT) Received: from 1Z10 ([37.163.238.51]) by smtp.gmail.com with ESMTPSA id 4fb4d7f45d1cf-6a5dea83a30sm3633147a12.15.2026.08.26.06.23.06 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 26 Aug 2026 06:23:07 -0700 (PDT) From: Maurizio Casciano To: linux-media@vger.kernel.org Cc: Mauro Carvalho Chehab , Sakari Ailus , Bingbu Cao , Jacopo Mondi , Nicholas Roth , Andy Shevchenko , Hans de Goede , Greg Kroah-Hartman , Jose Maria Martin , linux-staging@lists.linux.dev, linux-kernel@vger.kernel.org, Maurizio Casciano Subject: [PATCH 2/8] media: i2c: Add Yoga Book camera ACPI IDs Date: Wed, 26 Aug 2026 15:22:50 +0200 Message-ID: <20260826132256.3343451-3-mauriziocasciano7@gmail.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260826132256.3343451-1-mauriziocasciano7@gmail.com> References: <20260826132256.3343451-1-mauriziocasciano7@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The Lenovo Yoga Book YB1-X91 firmware enumerates the front OV2740 as OVTI2740 and the rear OV8858 as INT3477. Neither ID currently matches its sensor driver, so both I2C devices remain unbound. Add the IDs to the corresponding ACPI match tables. Sensor configuration and CSI lane quirks are kept in later patches. Signed-off-by: Maurizio Casciano Assisted-by: Codex:gpt-5.6-sol sparse --- drivers/media/i2c/ov2740.c | 1 + drivers/media/i2c/ov8858.c | 8 ++++++++ 2 files changed, 9 insertions(+) diff --git a/drivers/media/i2c/ov2740.c b/drivers/media/i2c/ov2740.c index 39003c1632ad..d85d83bdd203 100644 --- a/drivers/media/i2c/ov2740.c +++ b/drivers/media/i2c/ov2740.c @@ -1462,6 +1462,7 @@ static DEFINE_RUNTIME_DEV_PM_OPS(ov2740_pm_ops, ov274= 0_suspend, ov2740_resume, =20 static const struct acpi_device_id ov2740_acpi_ids[] =3D { {"INT3474"}, + {"OVTI2740"}, {} }; =20 diff --git a/drivers/media/i2c/ov8858.c b/drivers/media/i2c/ov8858.c index f2bed3e88382..5a97f21ab89d 100644 --- a/drivers/media/i2c/ov8858.c +++ b/drivers/media/i2c/ov8858.c @@ -6,6 +6,7 @@ * Copyright (c) 2017 Intel Corporation. */ =20 +#include #include #include #include @@ -2061,10 +2062,17 @@ static const struct of_device_id ov8858_of_match[] = =3D { }; MODULE_DEVICE_TABLE(of, ov8858_of_match); =20 +static const struct acpi_device_id ov8858_acpi_match[] =3D { + { "INT3477" }, + { /* sentinel */ }, +}; +MODULE_DEVICE_TABLE(acpi, ov8858_acpi_match); + static struct i2c_driver ov8858_i2c_driver =3D { .driver =3D { .name =3D "ov8858", .pm =3D &ov8858_pm_ops, + .acpi_match_table =3D ACPI_PTR(ov8858_acpi_match), .of_match_table =3D ov8858_of_match, }, .probe =3D ov8858_probe, --=20 2.53.0 From nobody Mon Sep 28 04:55:37 2026 Received: from mail-ed1-f50.google.com (mail-ed1-f50.google.com [209.85.208.50]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6D4F4424D57 for ; Wed, 26 Aug 2026 13:23:12 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.208.50 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787750595; cv=none; b=uS+sZ5n4vNCR9i2pZqHsslArZweQX8k6f4PKBj9UNP2T3MgtTxDAdk4m1Z2GOi/eW/OZ8FPHcIqVBmv3my1ZKdSAVFrICnxzjvdmO73F8Qy8WPtbMLEHjjFhFoyLI7o/WyJ1UGQAg4oDRzdvNAgfaFJWA4e3UHeix3Qr0r47x2w= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787750595; c=relaxed/simple; bh=s55Ii6QEsvGG1AvHe17eNCXjO9Ihg5gS51wo2byNVTg=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=kneMo8B3xDicnAXmuxY+uFYgeHYsLVFW8ISBTrUbmSg3N8L9oZyXVHtt8557oxzh+Kvwv5yuX0BQd7IcBEuJsCXmJyzoILIdruxwOmzOhIPKOFDwCpXX5zXaUbGJR3SZHsrpM0/QQlZzAcc3j/1tx7qIycnBbVGgtK8cH8m6pgM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=ibTRWEMp; arc=none smtp.client-ip=209.85.208.50 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="ibTRWEMp" Received: by mail-ed1-f50.google.com with SMTP id 4fb4d7f45d1cf-6a051904222so892697a12.2 for ; Wed, 26 Aug 2026 06:23:12 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1787750590; x=1788355390; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=+2BPxcfXD6mUVU6jhTybUN7wv/xdZ8rSO2UHVcgmlHg=; b=ibTRWEMplCUYvirEHALzbkzArGsObDxC7qYscA6PUXLkRcklRGl/JsPqst1HZtc7Vl EwP8KIK2qvjAo4r1ZpIloqRaNok3qJyH9iLEok8cSEzpu99ymOgUYl71zWeI/CUy0zO0 ignqj5FqtcUx9IPSyJ51TMXZyhBe1mt/9cLpykpGHFHRtubZuaKd5eRbHi5FNhfN7w+g AYUeJRvLl1SpAct7BziyOyNUfFWhmJ05d4UYzHGcZmvm142SjI6sWge1//T8iyCWHfWE WEaczTGPwwewXJmYechX2oxxxTU6rVSrs/ij3CcwVV78j4NxNF0xfd1yNB7CTw+C/BQp TuRg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1787750590; x=1788355390; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=+2BPxcfXD6mUVU6jhTybUN7wv/xdZ8rSO2UHVcgmlHg=; b=eXzWLNuuWMorCGBLcmYwc0fMSIFKc8P8DuJN55HSq2bO7fWYE4RlUbyRcgmXSw6zia bKYQOnXj7sT8fhNS+ZEZemc8w60pnXqoDZBvfPvE9ZAYLtVK+JAxjuMlSd0XM7Z8nI3K L/cPA7pwwV78ZVZJgShQKU65GVSW20775EHEtDEMv5fUGXK4kYTG4YjfmdO3f/UfKZ5x vv8CVjB1pPqcrYiiU5GhfW2bmrR9teARfw/k3YJatrfzz5UBaXf9C9ryyg64hJWtD8ZV U8qXAENTU6Tv4asXcepdwbK0kv6dkFm/Dwsdebq/wtDVNGrgDQFkITvKqvAFAwL67M+s k82w== X-Forwarded-Encrypted: i=1; AHgh+RoO+Zhov2pZQOjRIK1bDIyXPyOb0FrZlYSNgKHVvQGyyKG4v4nspBFFHXafgxtnkwlHhnYtFyzJfNtMb2U=@vger.kernel.org X-Gm-Message-State: AFuF++mC8F582q8ecgB674GJrdiu02jgUxzEUC1YLagHDgFRuOBL7Vmu Ei5fMBC58YY2JkOirrEkm/J2JUMiqTY84d/S9RwZc+SSguHFmLGIcRTKaqsVeP21 X-Gm-Gg: AR+sD10qoy4XKXBPz7hAA9ocT0JmIXA+75+KSWaHFGq8rHyo3dJdO9M6rNhPCxhRCN3 S37ISAQWXMnG1Ubcwezu62Uo+CRLUIoWJ7qia8mE6BUixMmMoqkgrmZ3np8Efxr+Fy7M1IXSw+G QIvE7cIX1Zc8DX4QWyG4kFM9u6Yh2FHWtjiaFTGlGNUY677ZdVQbLOs93kPpO1/hcBdUAV9PMEv IMD3yctgUtHRl5innTmB19DKU+m7dvU3Y9zzU9EHjuCDzuOzRtlTcaDQfPFXIg2W0yYcp34HULg N12SWFltnv1wqyv1sfxYGDt+2e55Q7+b/qiF3ZW7rnTAQjAFaskAY6q6FkWRlPkRrisgNewg/42 AA9no0eDaRFAiVDw/+38ZziuKtuD2D7NuNs3hq66wEa54YhP4UZZhcxR88pgfjYrLJPnCpQ3C+f KT6L7shVXwopEuEuaFwc1JleQUK6jcMSpKAm7OyT24qvRDeclYatzDYoa1PXG4XyjRt8J5rUDYu j8FTZI9FOGBqmFM5gQWCewd6+E7EeIB2BNY3u5jdUqKhlnQqHYnLg== X-Received: by 2002:a05:6402:21c6:b0:6a5:7aad:e75c with SMTP id 4fb4d7f45d1cf-6a5df61e239mr8437572a12.6.1787750590242; Wed, 26 Aug 2026 06:23:10 -0700 (PDT) Received: from 1Z10 ([37.163.238.51]) by smtp.gmail.com with ESMTPSA id 4fb4d7f45d1cf-6a5dea83a30sm3633147a12.15.2026.08.26.06.23.08 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 26 Aug 2026 06:23:09 -0700 (PDT) From: Maurizio Casciano To: linux-media@vger.kernel.org Cc: Mauro Carvalho Chehab , Sakari Ailus , Bingbu Cao , Jacopo Mondi , Nicholas Roth , Andy Shevchenko , Hans de Goede , Greg Kroah-Hartman , Jose Maria Martin , linux-staging@lists.linux.dev, linux-kernel@vger.kernel.org, Maurizio Casciano Subject: [PATCH 3/8] media: intel: ipu-bridge: Add Yoga Book camera sensors Date: Wed, 26 Aug 2026 15:22:51 +0200 Message-ID: <20260826132256.3343451-4-mauriziocasciano7@gmail.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260826132256.3343451-1-mauriziocasciano7@gmail.com> References: <20260826132256.3343451-1-mauriziocasciano7@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The Yoga Book YB1-X91 uses INT3477 for its OV8858 rear sensor and OVTI2740 for its OV2740 front sensor. Add link frequencies consumed by the sensor drivers when the IPU bridge constructs software endpoints. This supplies endpoint data only; it does not establish that either sensor can stream on the Yoga Book hardware. Signed-off-by: Maurizio Casciano Assisted-by: Codex:gpt-5.6-sol sparse --- drivers/media/pci/intel/ipu-bridge.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/media/pci/intel/ipu-bridge.c b/drivers/media/pci/intel= /ipu-bridge.c index 1bb3a3e98d6b..47317c423fad 100644 --- a/drivers/media/pci/intel/ipu-bridge.c +++ b/drivers/media/pci/intel/ipu-bridge.c @@ -65,6 +65,8 @@ static const struct ipu_sensor_config ipu_supported_senso= rs[] =3D { IPU_SENSOR_CONFIG("INT33F0", 1, 384000000), /* Omnivision OV2740 */ IPU_SENSOR_CONFIG("INT3474", 1, 180000000), + /* Omnivision OV8858 */ + IPU_SENSOR_CONFIG("INT3477", 1, 360000000), /* Omnivision OV5670 */ IPU_SENSOR_CONFIG("INT3479", 1, 422400000), /* Omnivision OV8865 */ @@ -93,6 +95,8 @@ static const struct ipu_sensor_config ipu_supported_senso= rs[] =3D { IPU_SENSOR_CONFIG("OVTIDB10", 1, 560000000), /* Omnivision OV2680 */ IPU_SENSOR_CONFIG("OVTI2680", 1, 331200000), + /* Omnivision OV2740 */ + IPU_SENSOR_CONFIG("OVTI2740", 1, 360000000), /* Omnivision OV5675 */ IPU_SENSOR_CONFIG("OVTI5675", 1, 450000000), /* Omnivision OV8856 */ --=20 2.53.0 From nobody Mon Sep 28 04:55:37 2026 Received: from mail-ed1-f41.google.com (mail-ed1-f41.google.com [209.85.208.41]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 455114279FE for ; Wed, 26 Aug 2026 13:23:14 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.208.41 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787750597; cv=none; b=gAIn2sVx5lTeeM6LndQhIyFM5oCJTtGWhRLnXlBHx7h+60oihSF9yPGABgBXYEh1c6t3sDGq7+18Lg22RBGoewEbewTh5vU6Kky/eepTGY0HCsBbYcCeR87VY6X3lWrPf4f/TMHEFFZBh+AyjBxG1l7egIYBFI00uSRsAvLBNZE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787750597; c=relaxed/simple; bh=zNg9hW5D8DfY6cxbJI9eBWDVBL+I9NugvrjlC/Bu+EA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=RlrwbNnNBcozERxQSA57TODDYrwqRml2lj0HzxXrcDNVTIZchcuy1pbKFyO/Cl5rVJwXNETHmCRH9SC8yS1K/+hQ63yrZGXYVd7lrWFMzwDTr2LirJld29OP7sdvOECpXKGpal7295S5zg/x4Xx1PkFYr15WXko+TwQ8gYhvg9I= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=JhfodGBN; arc=none smtp.client-ip=209.85.208.41 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="JhfodGBN" Received: by mail-ed1-f41.google.com with SMTP id 4fb4d7f45d1cf-6a173ad7cf4so1578184a12.3 for ; Wed, 26 Aug 2026 06:23:14 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1787750592; x=1788355392; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=FKiURqLEO6GLiHVAiPzakCM7/0KgqMwtzahpI4nlMQg=; b=JhfodGBNpfg6bZscARG9T3kdC9eRU+3iCEBGesniwfjIazOSVnzKiXAwTZgm5uipGU x5V/koSRPCNyz9wjjaK8uy9Z7M7bCrTP8l+tFyAgMym/n7IVNZry2kbRoYhs62jLzE4c t7JsrXW2JMG1hPcaP8gxm6ofpqap0oHAKa4CHF7ADhbXl10re199NeGf69TGuIxEhUYJ ZAnWPI7m129PUha3THIFsD/rsqnaB2rCxSStsm4NMnNrnXGJmKpRLUM12a0NRc/GiU71 Y5UpkAKC4yC/GRDRZXEfzcGndc7hugm9gwuXFA8++FjxD7snWZuedHko5lGjBEXex6V+ KeDQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1787750592; x=1788355392; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=FKiURqLEO6GLiHVAiPzakCM7/0KgqMwtzahpI4nlMQg=; b=bCDLcBtuHxWh1iDiQQXCwRGTe/Qaa3ejf9K2NRPG+M7qYmidpEPe8kFAFfjOzSonSV WyExjpGhnO0x5WoYP8ZbWQ0OxTOonInLWkJ1amA47riIbNWS2YW+PKJhem4ay6yAHt0S fPqz5XReZYx0VXXbHjyk+7miqV3k7MtMRqr3KBV0F2TNJdgsR1EdzEmgeA/HU0MdwHJS bUHQkuwUo4xcWgjTltOLaBYMst+hjbPCfKk385qoEj/Wlb2AN5UBts9waIKvaNhqxNcD NQRT6QCnlD1cFYQLkjIl3bua+/8BHYRJ8QLblT+tVkIA2ExTpA2X9ulWmLM5IehvaYqD mhzg== X-Forwarded-Encrypted: i=1; AHgh+RpHCEm60xeFvYC87aR0UVpUUSZtXtXfxMC2jhxoBN5ohStZKig9/dwdlHy37BzT8H/izIyx08aLKHWkZJk=@vger.kernel.org X-Gm-Message-State: AFuF++kwId2hadms1I5VXQDs/EL2F5uNI4Ors8Jk45WHGB0IFdaBZIkt teeInqWvECQqS6/7UG3hEOFrT0u+dxqh+5/S5YMDv8a/7GuRqZTSC/Tb X-Gm-Gg: AR+sD13Q1IeJM4a3BwqygVkUcn5jqmcGgVAaOxgz24z9nbG9P+JCC3uOANwt/SZJD5g xoqGkcM1BKTKeINEPZjPFQ5NkG13gCDHAuEaZOert2QuKCmdwqbKcFiGL6N95yMfl8g+6NoTv45 3aVdXXurPIoUxUR910yTJsym6Kc+BFZVyPB1cRmN+CHYSxM9+2c864NmrFr2w8pyZSdvSSMTr/3 0+rtW/ZuepJeNQORcjB29QMITDL5i3NKMxIdNM0KCx1MZb17k38RZSF5JMRS9ynK87HCOrppjne Lticy53SQWDu2yBOYBIgoP3SVTLzifjyBUJBw7VCveytzrqlAdXOEFzH73erw3cH2TrT0yMJDAA /IwRvWbyJse2HkMh+UHqckHnIK8M/4PhcvrrLFFBIAefD5eqJQG1myKPT9r0FqeVtEsA7TAFBll MxSS/oKPG8hZ3qQ4fW/YvyDtNx0Yy7JPvq1+909mqdps0yC0ZGuWG/6Nte1svA1SrXFMLK0ByB8 KqRftR8ZJFyExs0OTKjmWudaePSN1r8hDHUK2bZSk0= X-Received: by 2002:a05:6402:5057:b0:6a5:dd97:23ea with SMTP id 4fb4d7f45d1cf-6a5df65b681mr8136749a12.11.1787750592156; Wed, 26 Aug 2026 06:23:12 -0700 (PDT) Received: from 1Z10 ([37.163.238.51]) by smtp.gmail.com with ESMTPSA id 4fb4d7f45d1cf-6a5dea83a30sm3633147a12.15.2026.08.26.06.23.10 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 26 Aug 2026 06:23:11 -0700 (PDT) From: Maurizio Casciano To: linux-media@vger.kernel.org Cc: Mauro Carvalho Chehab , Sakari Ailus , Bingbu Cao , Jacopo Mondi , Nicholas Roth , Andy Shevchenko , Hans de Goede , Greg Kroah-Hartman , Jose Maria Martin , linux-staging@lists.linux.dev, linux-kernel@vger.kernel.org, Maurizio Casciano Subject: [PATCH 4/8] media: atomisp: Add Yoga Book camera configuration Date: Wed, 26 Aug 2026 15:22:52 +0200 Message-ID: <20260826132256.3343451-5-mauriziocasciano7@gmail.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260826132256.3343451-1-mauriziocasciano7@gmail.com> References: <20260826132256.3343451-1-mauriziocasciano7@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The Yoga Book YB1-X91 firmware lacks usable AtomISP configuration for both cameras. Rear INT3477 OV8858 uses four CSI-2 lanes and a WV517S actuator; front OVTI2740 uses two lanes and no actuator. Add both sensor configurations and a DMI-scoped two-lane override for OVTI2740:00. Keep the quirk limited to Lenovo YB1-X91L systems. Binding and media nodes do not prove streaming; both sensors and the focus actuator still require physical tests. Signed-off-by: Maurizio Casciano Assisted-by: Codex:gpt-5.6-sol sparse --- .../media/atomisp/pci/atomisp_csi2_bridge.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/drivers/staging/media/atomisp/pci/atomisp_csi2_bridge.c b/driv= ers/staging/media/atomisp/pci/atomisp_csi2_bridge.c index cca91c6d71a5..207ab69385b5 100644 --- a/drivers/staging/media/atomisp/pci/atomisp_csi2_bridge.c +++ b/drivers/staging/media/atomisp/pci/atomisp_csi2_bridge.c @@ -74,6 +74,12 @@ static struct gmin_cfg_var lenovo_ideapad_miix_310_vars[= ] =3D { {} }; =20 +static struct gmin_cfg_var lenovo_yogabook_x91_vars[] =3D { + /* The vendor driver and sensor modes use two CSI data lanes. */ + { "OVTI2740:00", "CsiLanes", "2" }, + {} +}; + static struct gmin_cfg_var xiaomi_mipad2_vars[] =3D { /* _DSM contains the wrong CsiPort for the front facing OV5693 sensor */ { "INT33BE:00", "CsiPort", "0" }, @@ -83,6 +89,14 @@ static struct gmin_cfg_var xiaomi_mipad2_vars[] =3D { }; =20 static const struct dmi_system_id gmin_cfg_dmi_overrides[] =3D { + { + /* Lenovo Yoga Book X91L */ + .matches =3D { + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_NAME, "Lenovo YB1-X91L"), + }, + .driver_data =3D lenovo_yogabook_x91_vars, + }, { /* Lenovo Ideapad Miix 310 */ .matches =3D { @@ -360,6 +374,8 @@ static const struct acpi_device_id atomisp_sensor_confi= gs[] =3D { * an i2c-client for the VCM, so it is disabled for now. */ ATOMISP_SENSOR_CONFIG("INT33BE", 2, false), /* OV5693 */ + ATOMISP_SENSOR_CONFIG("INT3477", 4, true), /* OV8858 */ + ATOMISP_SENSOR_CONFIG("OVTI2740", 2, false), /* OV2740 */ {} }; =20 --=20 2.53.0 From nobody Mon Sep 28 04:55:37 2026 Received: from mail-ed1-f49.google.com (mail-ed1-f49.google.com [209.85.208.49]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A2410425860 for ; Wed, 26 Aug 2026 13:23:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.208.49 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787750600; cv=none; b=u1hovZWsbcNjWnZVa3hyxKA/EMTGtrq4Hc6VntiwM4Ef8CZwtINjf+28r1ymsQPwX5xsyjd3FM47PWr71RnD4+frcDPmCOLlAVlTv676C7vt0Wo23SbxDaYsaOzzTK7qMZkK9mj0sUfNezvlo+n63CDzOYFnStmlfIWnWhrcB+c= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787750600; c=relaxed/simple; bh=LyLoXF6tXMwCiKPgithzn41UgyMWaC02Owk4FkJ0mXk=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=eOTkbmNAau1JeqfdHimjroeXMr1y/DHO9T691e07ubI7dr1pX0hMdKju2CJrL1MhT6uMDbn/P0LJiH+zJeRBZV1EjG6z1Kx8swIguDSxk+FiiRYNKy+lhM09NCLdzHE+r2vOjB0+0eUUAINFx2k0vdQpR7z+2Ag26D/Th8fSFRA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=RoQA1+hG; arc=none smtp.client-ip=209.85.208.49 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="RoQA1+hG" Received: by mail-ed1-f49.google.com with SMTP id 4fb4d7f45d1cf-6a422090b2fso1312512a12.0 for ; Wed, 26 Aug 2026 06:23:16 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1787750594; x=1788355394; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=7hUd20GpxQCc4d41YDgQHUkh4hezfHFKYEHRgbx10eE=; b=RoQA1+hGFsL/agJo8NFL1ldYJKMGSQExZRPn+u10B8n5mBXY8+6qutKz7/A1S24W9Y LfE+TIiUIoTx8UaywPrJhGNeKQ3d3CFFQbO2HzTcZpDBEgp0oCi4YvqFSrAAxeX/P4j9 otxVkKp/5WTqn3qrjhOl7TzVB7biq1kHRVVfnme6JK49kSVvIYZx3xuaFHnZNFziVI2w itH9UPwFKncj3Jam5mF10I78dcczPHe6Oeuba0ivh8k1y9mgrtF3xi6AbB6LiTMiJ01+ uD7LmYw+W0h/Sk+Xn87bfdlni+Fxh7Q/zs+w7kiDxNDP873Fx6U85S1+5sCSYDMfHYOL RLfQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1787750594; x=1788355394; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=7hUd20GpxQCc4d41YDgQHUkh4hezfHFKYEHRgbx10eE=; b=AkMZfK5aPzDW0/PpSOt3kAc0OKov+uXOLEIA7jJQIfFHvOpgkfzmuaO73ro8nizsKp OgFP+hWdwbDqp8Yy6fg6oLUMeM41eAQplGwlDqqQ6uh4QRTJEe6uCyMqHn1ds3AjBe6P VYBP7EpO9ufuYjZ1MNee7L99FRMFcLSj/b9tppHGEQUe1wGQgcv6CbN3lM79+WG2c1Nz CplseeEgvKaNYioZ1J1JITimMYHCjjn93LnXha2Qn6RbuMiSP3cvhCEqckqJmZXp64Ip 8KK5ve1jL0KYmbfKCWFvfMvXohnifGmwCGglyWglY41yYYdSmdCbMmAwWqMif6eL+1ys 98rg== X-Forwarded-Encrypted: i=1; AHgh+Rp1qe4t9MrbsRney9tJoqmURouXSZ5mUAvuCwzPljd4C/9UW4Zj8FTzcnzfKiQ+Fui9nt5hVXsOWAe5WRg=@vger.kernel.org X-Gm-Message-State: AFuF++mzis245fVUvAb/OsErW6gIYLn4VFGIjTU4nFbQfgK8OKEWpmye 77gKtgkKmSCQdjfxFdhV+kXs2Z2ln64qWrJHN26osbbFg6YNCuAZuP0X X-Gm-Gg: AR+sD12bp+LnDfL+k13NAZK5lRdvJJ9UBvXFo5nlsL3OS2tmFW51ra7+MX3sHOQxTPT hyNPvpMZnm3dLuHhbmxmGMj8zPLtvd9BORuAw30pDsrx0+SrjMhaQpsHhAHf6kJfVzBvMMEKDx8 xaqEokpGNjgwfvav8P5e2WW8wPLw8BIHCDuzI0p5vQPUUZdcD+Fjrm4I+8aMT6PikTCJY/r+HGa yrUze2ftPUJOiVe09nwGMPERejQUvnAveDAPtTl/VJNww/7oIjGDaAXMQprA1RgM5KHMacghXHj 4aEYjvK/peevjNN5LluGYPE9eXtp/aNnMpD0ZMNafA81p+iEJMDwmYrXq3/BaSW2pj9Uc+ZwPx7 ijiH47iFeNvvTrvCWGd+D8yBkndrcXLBGHN+q2YOxCX2tFPSM9JxrSz38fvTIfboeSVwEO+4Rux fX4bTvUIVi5u9iIuKYrF0O3BpPtC+O6CK7sRDyT22bwBxoUIEl+ExNchUlUz2nyU5vIa4Osd1Bn pkZQ1EYa+OGx/MPL7WnwLnaIuVEM4oV5AFp5sRtuEuh55hocDk5Ow== X-Received: by 2002:a05:6402:2742:b0:6a1:4fc7:94b3 with SMTP id 4fb4d7f45d1cf-6a5df5b04b8mr8718503a12.1.1787750594285; Wed, 26 Aug 2026 06:23:14 -0700 (PDT) Received: from 1Z10 ([37.163.238.51]) by smtp.gmail.com with ESMTPSA id 4fb4d7f45d1cf-6a5dea83a30sm3633147a12.15.2026.08.26.06.23.12 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 26 Aug 2026 06:23:13 -0700 (PDT) From: Maurizio Casciano To: linux-media@vger.kernel.org Cc: Mauro Carvalho Chehab , Sakari Ailus , Bingbu Cao , Jacopo Mondi , Nicholas Roth , Andy Shevchenko , Hans de Goede , Greg Kroah-Hartman , Jose Maria Martin , linux-staging@lists.linux.dev, linux-kernel@vger.kernel.org, Maurizio Casciano Subject: [PATCH 5/8] media: atomisp: support the Yoga Book OV2740 link Date: Wed, 26 Aug 2026 15:22:53 +0200 Message-ID: <20260826132256.3343451-6-mauriziocasciano7@gmail.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260826132256.3343451-1-mauriziocasciano7@gmail.com> References: <20260826132256.3343451-1-mauriziocasciano7@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The YB1-X91L firmware does not describe the complete camera link. Its front OV2740 uses two CSI-2 lanes at a 288 MHz link frequency and sends a 1932x1092 BGGR transport frame with 12 pixels of horizontal and vertical padding around the 1920x1080 image. Allow the AtomISP bridge to provide per-sensor link frequencies and padding, add the matching OV2740 mode, and derive ISP2401 D-PHY timing from the sensor link-frequency control. The register values are hardware configuration facts checked against the Lenovo YB1-X91L configuration and physical captures; no proprietary driver code or tuning binary is included. Tested on a Lenovo Yoga Book YB1-X91L with continuous front-camera raw capture. Signed-off-by: Maurizio Casciano Assisted-by: Codex:gpt-5.6-sol sparse --- drivers/media/i2c/ov2740.c | 98 ++++++++++++++++++- drivers/media/pci/intel/ipu-bridge.c | 15 ++- .../staging/media/atomisp/pci/atomisp_csi2.c | 17 +++- .../staging/media/atomisp/pci/atomisp_csi2.h | 2 + .../media/atomisp/pci/atomisp_csi2_bridge.c | 65 ++++++++++++ include/media/ipu-bridge.h | 2 + 6 files changed, 186 insertions(+), 13 deletions(-) diff --git a/drivers/media/i2c/ov2740.c b/drivers/media/i2c/ov2740.c index d85d83bdd203..b760d4dc0e68 100644 --- a/drivers/media/i2c/ov2740.c +++ b/drivers/media/i2c/ov2740.c @@ -17,6 +17,7 @@ #include =20 #define OV2740_LINK_FREQ_360MHZ 360000000ULL +#define OV2740_LINK_FREQ_288MHZ 288000000ULL #define OV2740_LINK_FREQ_180MHZ 180000000ULL #define OV2740_SCLK 72000000LL #define OV2740_MCLK 19200000 @@ -91,6 +92,7 @@ struct nvm_data { =20 enum { OV2740_LINK_FREQ_360MHZ_INDEX, + OV2740_LINK_FREQ_288MHZ_INDEX, OV2740_LINK_FREQ_180MHZ_INDEX, }; =20 @@ -130,8 +132,14 @@ struct ov2740_mode { /* Link frequency needed for this resolution */ u32 link_freq_index; =20 + /* Optional common settings applied before the mode-specific settings */ + const struct ov2740_reg_list init_reg_list; + /* Sensor register settings for this resolution */ const struct ov2740_reg_list reg_list; + + /* Bayer order produced by this mode */ + u32 code; }; =20 static const struct ov2740_reg mipi_data_rate_720mbps[] =3D { @@ -142,6 +150,14 @@ static const struct ov2740_reg mipi_data_rate_720mbps[= ] =3D { {0x0312, 0x11}, }; =20 +static const struct ov2740_reg mipi_data_rate_576mbps[] =3D { + {0x0302, 0x1e}, + {0x0303, 0x00}, + {0x030d, 0x1e}, + {0x030e, 0x02}, + {0x0312, 0x01}, +}; + static const struct ov2740_reg mipi_data_rate_360mbps[] =3D { {0x0302, 0x4b}, {0x0303, 0x01}, @@ -458,6 +474,36 @@ static const struct ov2740_reg mode_1932x1092_regs_180= mhz[] =3D { {0x4003, 0x40}, /* set Black level to 0x40 */ }; =20 +/* + * Lenovo's Yoga Book vendor driver uses the generic initialization settin= gs + * above followed by these mode overrides. Unlike the generic 720 Mbps mo= de, + * this is a 576 Mbps two-lane mode with BGGR output from the optical arra= y. + */ +static const struct ov2740_reg mode_1932x1092_regs_288mhz[] =3D { + {0x0302, 0x1e}, + {0x0303, 0x00}, + {0x030d, 0x1e}, + {0x030e, 0x02}, + {0x0312, 0x01}, + {0x3808, 0x07}, + {0x3809, 0x8c}, + {0x380a, 0x04}, + {0x380b, 0x44}, + {0x380c, 0x04}, + {0x380d, 0x38}, + {0x380e, 0x06}, + {0x380f, 0xf0}, + {0x3810, 0x00}, + {0x3811, 0x02}, + {0x3812, 0x00}, + {0x3813, 0x02}, + {0x481f, 0x29}, + {0x4820, 0x01}, + {0x4837, 0x1b}, + {0x5000, 0x7f}, + {0x58f4, 0x32}, +}; + static const char * const ov2740_test_pattern_menu[] =3D { "Disabled", "Color Bar", @@ -468,6 +514,7 @@ static const char * const ov2740_test_pattern_menu[] = =3D { =20 static const s64 link_freq_menu_items[] =3D { OV2740_LINK_FREQ_360MHZ, + OV2740_LINK_FREQ_288MHZ, OV2740_LINK_FREQ_180MHZ, }; =20 @@ -478,6 +525,12 @@ static const struct ov2740_link_freq_config link_freq_= configs[] =3D { .regs =3D mipi_data_rate_720mbps, } }, + [OV2740_LINK_FREQ_288MHZ_INDEX] =3D { + .reg_list =3D { + .num_of_regs =3D ARRAY_SIZE(mipi_data_rate_576mbps), + .regs =3D mipi_data_rate_576mbps, + } + }, [OV2740_LINK_FREQ_180MHZ_INDEX] =3D { .reg_list =3D { .num_of_regs =3D ARRAY_SIZE(mipi_data_rate_360mbps), @@ -499,6 +552,28 @@ static const struct ov2740_mode supported_modes_360mhz= [] =3D { .regs =3D mode_1932x1092_regs_360mhz, }, .link_freq_index =3D OV2740_LINK_FREQ_360MHZ_INDEX, + .code =3D MEDIA_BUS_FMT_SGRBG10_1X10, + }, +}; + +static const struct ov2740_mode supported_modes_288mhz[] =3D { + { + .width =3D 1932, + .height =3D 1092, + .hts =3D 2160, + .vts_min =3D 1776, + .vts_def =3D 1776, + .vts_max =3D 32767, + .init_reg_list =3D { + .num_of_regs =3D ARRAY_SIZE(mode_1932x1092_regs_360mhz), + .regs =3D mode_1932x1092_regs_360mhz, + }, + .reg_list =3D { + .num_of_regs =3D ARRAY_SIZE(mode_1932x1092_regs_288mhz), + .regs =3D mode_1932x1092_regs_288mhz, + }, + .link_freq_index =3D OV2740_LINK_FREQ_288MHZ_INDEX, + .code =3D MEDIA_BUS_FMT_SBGGR10_1X10, }, }; =20 @@ -515,6 +590,7 @@ static const struct ov2740_mode supported_modes_180mhz[= ] =3D { .regs =3D mode_1932x1092_regs_180mhz, }, .link_freq_index =3D OV2740_LINK_FREQ_180MHZ_INDEX, + .code =3D MEDIA_BUS_FMT_SGRBG10_1X10, }, }; =20 @@ -842,7 +918,7 @@ static void ov2740_update_pad_format(const struct ov274= 0_mode *mode, { fmt->width =3D mode->width; fmt->height =3D mode->height; - fmt->code =3D MEDIA_BUS_FMT_SGRBG10_1X10; + fmt->code =3D mode->code; fmt->field =3D V4L2_FIELD_NONE; } =20 @@ -966,6 +1042,15 @@ static int ov2740_start_streaming(struct ov2740 *ov27= 40) return ret; } =20 + if (ov2740->cur_mode->init_reg_list.num_of_regs) { + reg_list =3D &ov2740->cur_mode->init_reg_list; + ret =3D ov2740_write_reg_list(ov2740, reg_list); + if (ret) { + dev_err(ov2740->dev, "failed to set common mode registers\n"); + return ret; + } + } + reg_list =3D &ov2740->cur_mode->reg_list; ret =3D ov2740_write_reg_list(ov2740, reg_list); if (ret) { @@ -1062,10 +1147,12 @@ static int ov2740_enum_mbus_code(struct v4l2_subdev= *sd, struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { + struct ov2740 *ov2740 =3D to_ov2740(sd); + if (code->index > 0) return -EINVAL; =20 - code->code =3D MEDIA_BUS_FMT_SGRBG10_1X10; + code->code =3D ov2740->supported_modes[0].code; =20 return 0; } @@ -1080,7 +1167,7 @@ static int ov2740_enum_frame_size(struct v4l2_subdev = *sd, if (fse->index >=3D ov2740->supported_modes_count) return -EINVAL; =20 - if (fse->code !=3D MEDIA_BUS_FMT_SGRBG10_1X10) + if (fse->code !=3D supported_modes[0].code) return -EINVAL; =20 fse->min_width =3D supported_modes[fse->index].width; @@ -1178,6 +1265,11 @@ static int ov2740_check_hwcfg(struct ov2740 *ov2740) ov2740->supported_modes_count =3D ARRAY_SIZE(supported_modes_360mhz); break; + case OV2740_LINK_FREQ_288MHZ_INDEX: + ov2740->supported_modes =3D supported_modes_288mhz; + ov2740->supported_modes_count =3D + ARRAY_SIZE(supported_modes_288mhz); + break; case OV2740_LINK_FREQ_180MHZ_INDEX: ov2740->supported_modes =3D supported_modes_180mhz; ov2740->supported_modes_count =3D diff --git a/drivers/media/pci/intel/ipu-bridge.c b/drivers/media/pci/intel= /ipu-bridge.c index 47317c423fad..5730a95767a2 100644 --- a/drivers/media/pci/intel/ipu-bridge.c +++ b/drivers/media/pci/intel/ipu-bridge.c @@ -520,11 +520,16 @@ static void ipu_bridge_create_fwnode_properties( sensor->prop_names.remote_endpoint, sensor->local_ref); =20 - if (cfg->nr_link_freqs > 0) - sensor->ep_properties[3] =3D PROPERTY_ENTRY_U64_ARRAY_LEN( - sensor->prop_names.link_frequencies, - cfg->link_freqs, - cfg->nr_link_freqs); + if (sensor->nr_link_freqs > 0) + sensor->ep_properties[3] =3D + PROPERTY_ENTRY_U64_ARRAY_LEN(names->link_frequencies, + sensor->link_freqs, + sensor->nr_link_freqs); + else if (cfg->nr_link_freqs > 0) + sensor->ep_properties[3] =3D + PROPERTY_ENTRY_U64_ARRAY_LEN(names->link_frequencies, + cfg->link_freqs, + cfg->nr_link_freqs); =20 sensor->ipu_properties[0] =3D PROPERTY_ENTRY_U32_ARRAY_LEN( sensor->prop_names.data_lanes, diff --git a/drivers/staging/media/atomisp/pci/atomisp_csi2.c b/drivers/sta= ging/media/atomisp/pci/atomisp_csi2.c index 95b9113d75e9..035f1addeaae 100644 --- a/drivers/staging/media/atomisp/pci/atomisp_csi2.c +++ b/drivers/staging/media/atomisp/pci/atomisp_csi2.c @@ -5,6 +5,7 @@ * Copyright (c) 2010 Intel Corporation. All Rights Reserved. */ =20 +#include #include #include #include "atomisp_cmd.h" @@ -288,18 +289,19 @@ static void atomisp_csi2_configure_isp2401(struct ato= misp_sub_device *asd) int dat_termen; int dat_settle; =20 - struct v4l2_control ctrl; struct atomisp_device *isp =3D asd->isp; + struct v4l2_subdev *sensor; + s64 link_freq; int mipi_freq =3D 0; enum atomisp_camera_port port; int n; =20 port =3D isp->inputs[asd->input_curr].port; =20 - ctrl.id =3D V4L2_CID_LINK_FREQ; - if (v4l2_g_ctrl - (isp->inputs[asd->input_curr].sensor->ctrl_handler, &ctrl) =3D=3D 0) - mipi_freq =3D ctrl.value; + sensor =3D isp->inputs[asd->input_curr].sensor; + link_freq =3D v4l2_get_link_freq(&sensor->entity.pads[0], 0, 0); + if (link_freq > 0 && link_freq <=3D S32_MAX) + mipi_freq =3D link_freq; =20 clk_termen =3D atomisp_csi2_configure_calc(coeff_clk_termen, mipi_freq, TERMEN_DEFAULT); @@ -310,6 +312,11 @@ static void atomisp_csi2_configure_isp2401(struct atom= isp_sub_device *asd) dat_settle =3D atomisp_csi2_configure_calc(coeff_dat_settle, mipi_freq, SETTLE_DEFAULT); =20 + dev_dbg(isp->dev, + "CSI port %u link frequency %d Hz, clk timing %d/%d, data timing %d/%d\n= ", + port, mipi_freq, clk_termen, clk_settle, + dat_termen, dat_settle); + for (n =3D 0; n < csi2_port_lanes[port] + 1; n++) { hrt_address base =3D csi2_port_base[port] + csi2_lane_base[n]; =20 diff --git a/drivers/staging/media/atomisp/pci/atomisp_csi2.h b/drivers/sta= ging/media/atomisp/pci/atomisp_csi2.h index ec762f8fb922..dd36659e7984 100644 --- a/drivers/staging/media/atomisp/pci/atomisp_csi2.h +++ b/drivers/staging/media/atomisp/pci/atomisp_csi2.h @@ -45,6 +45,8 @@ int atomisp_mipi_csi2_register_entities(struct atomisp_mi= pi_csi2_device *csi2, struct v4l2_device *vdev); int atomisp_csi2_bridge_init(struct atomisp_device *isp); int atomisp_csi2_bridge_parse_firmware(struct atomisp_device *isp); +bool atomisp_csi2_get_sensor_padding(struct device *dev, u32 *padding_w, + u32 *padding_h); =20 void atomisp_csi2_configure(struct atomisp_sub_device *asd); =20 diff --git a/drivers/staging/media/atomisp/pci/atomisp_csi2_bridge.c b/driv= ers/staging/media/atomisp/pci/atomisp_csi2_bridge.c index 207ab69385b5..0b9577ffb98c 100644 --- a/drivers/staging/media/atomisp/pci/atomisp_csi2_bridge.c +++ b/drivers/staging/media/atomisp/pci/atomisp_csi2_bridge.c @@ -77,6 +77,11 @@ static struct gmin_cfg_var lenovo_ideapad_miix_310_vars[= ] =3D { static struct gmin_cfg_var lenovo_yogabook_x91_vars[] =3D { /* The vendor driver and sensor modes use two CSI data lanes. */ { "OVTI2740:00", "CsiLanes", "2" }, + /* The vendor 1932x1092 mode uses a 576 Mbps two-lane link. */ + { "OVTI2740:00", "CsiLinkFreq", "288000000" }, + /* Crop the vendor mode's 1932x1092 transport frame to 1920x1080. */ + { "OVTI2740:00", "CsiPaddingWidth", "12" }, + { "OVTI2740:00", "CsiPaddingHeight", "12" }, {} }; =20 @@ -207,6 +212,49 @@ static int gmin_cfg_get_int(struct acpi_device *adev, = const char *key, int defau return default_val; } =20 +bool atomisp_csi2_get_sensor_padding(struct device *dev, u32 *padding_w, + u32 *padding_h) +{ + struct acpi_device *adev =3D ACPI_COMPANION(dev); + bool override =3D false; + char *str_val; + unsigned int val; + + *padding_w =3D pad_w; + *padding_h =3D pad_h; + + if (!adev) + return false; + + str_val =3D gmin_cfg_get(adev, "CsiPaddingWidth"); + if (str_val) { + if (!kstrtouint(str_val, 0, &val) && val <=3D 64 && !(val & 1)) { + *padding_w =3D val; + override =3D true; + } else { + acpi_handle_warn(adev->handle, + "%s: Invalid CSI padding width %s\n", + dev_name(dev), str_val); + } + kfree(str_val); + } + + str_val =3D gmin_cfg_get(adev, "CsiPaddingHeight"); + if (str_val) { + if (!kstrtouint(str_val, 0, &val) && val <=3D 64 && !(val & 1)) { + *padding_h =3D val; + override =3D true; + } else { + acpi_handle_warn(adev->handle, + "%s: Invalid CSI padding height %s\n", + dev_name(dev), str_val); + } + kfree(str_val); + } + + return override; +} + static int atomisp_csi2_get_pmc_clk_nr_from_acpi_pr0(struct acpi_device *a= dev) { /* ACPI_PATH_SEGMENT_LENGTH is guaranteed to be big enough for name + 0 t= erm. */ @@ -383,6 +431,8 @@ static int atomisp_csi2_parse_sensor_fwnode(struct acpi= _device *adev, struct ipu_sensor *sensor) { const struct acpi_device_id *id; + char *link_freq_str; + unsigned long long link_freq; int ret, clock_num; bool vcm =3D false; int lanes =3D 1; @@ -422,6 +472,21 @@ static int atomisp_csi2_parse_sensor_fwnode(struct acp= i_device *adev, return -EINVAL; } =20 + link_freq_str =3D gmin_cfg_get(adev, "CsiLinkFreq"); + if (link_freq_str) { + ret =3D kstrtoull(link_freq_str, 0, &link_freq); + kfree(link_freq_str); + if (ret || !link_freq) { + acpi_handle_err(adev->handle, + "%s: Invalid CSI link frequency\n", + dev_name(&adev->dev)); + return ret ?: -EINVAL; + } + + sensor->link_freqs[0] =3D link_freq; + sensor->nr_link_freqs =3D 1; + } + ret =3D atomisp_csi2_add_gpio_mappings(adev); if (ret) return ret; diff --git a/include/media/ipu-bridge.h b/include/media/ipu-bridge.h index 16fac765456e..633ef0c4cf59 100644 --- a/include/media/ipu-bridge.h +++ b/include/media/ipu-bridge.h @@ -135,6 +135,8 @@ struct ipu_sensor { =20 u8 link; u8 lanes; + u8 nr_link_freqs; + u64 link_freqs[MAX_NUM_LINK_FREQS]; u32 mclkspeed; u32 rotation; enum v4l2_fwnode_orientation orientation; --=20 2.53.0 From nobody Mon Sep 28 04:55:37 2026 Received: from mail-ed1-f52.google.com (mail-ed1-f52.google.com [209.85.208.52]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 922AA415B76 for ; Wed, 26 Aug 2026 13:23:18 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.208.52 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787750602; cv=none; b=jC8wraWQ6i3MUlOFIJnRccoKnbJnunMaF/cHjRx23y0AkWRvYncHpPLVStt1v7krgGIbJPYd06jMe2vyPilthzQMkifmNvxtqqtkSVPx9ShgFCyryxhUhB8R2f2O0EoyjbAycr9KStb1XCcyDdoVt68vIqKd3smwuRdWvwi32UE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787750602; c=relaxed/simple; bh=THMn0luMX4cku0CmD3upSa4VhiQXQXukK48ACXoBa6o=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=QUmUlPLLGS0hNHGo5wGk4g6Q2ryFLIFjOv5CKyQZofSzS6f05eItQZMAfTyZIKvpvnVB0QWCVeYpL0v8Rvcdhh/uv624g9Lnu5XDspyR+UWxm9Akmd0anBrCDMFLrBlQvNan0+4DNoxaTYNzX3nG92q/IoHBXURih+knbppfhJc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=ECx4eLn0; arc=none smtp.client-ip=209.85.208.52 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="ECx4eLn0" Received: by mail-ed1-f52.google.com with SMTP id 4fb4d7f45d1cf-6a051904222so892863a12.2 for ; Wed, 26 Aug 2026 06:23:18 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1787750596; x=1788355396; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=1BJDJIpJZRxZ10l5Jed80WVNk6QVcCkQrV78n6UBbUM=; b=ECx4eLn0xDhrWwHqvDK1V4AD0X2kjhnDdhXoJf19m69heNvGJJCjkri39Qza/Qe+T1 oxjFfSJXNPQbM4HEw9KPHFHdpvzGXpBMSEdlAUvcki2nznzB0EEbxZPdrjEuih45R0lW HbjJ11lNOBJo3AjM7CHdeEHyWGxu3DOEALt0CN5bMNchZviyjh3zYKcyD0jPTCz+SoQ0 HjiBLSdyOXrU4n20gXekw2DHqz3w+zT+r/JH5N2cElsrRKUri+s1mFiAfaguEx6Kidlc nCG2SzKE/VJ56szqSmq+W+ducqMtzALXLuF6nwOGvU6dGCJbqdnObRviVVTB4p1pAIR9 /Scg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1787750596; x=1788355396; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=1BJDJIpJZRxZ10l5Jed80WVNk6QVcCkQrV78n6UBbUM=; b=oDl/0uIeK86QxTA6X8j9WPpeheAEjTsIx4qhTfa7FSrph5vcY3MT42g6kGlOH+JUR9 U7To5CGzLM8s/B+oSsmuNG6jhgUzqda1T8cehmuoAnn316EOf7qouehix3muD7DYvt7h TZ8331HykidP9u1RiioEWiwr9WWD1vRT2MFpxLUlCsBn3kPCVgM32/fFlcKsBMtVpxIG 8EwdmXcl8+hYxJTLqa81EU5JflT9pom0+cmQjyXGh7H5B1IJJVfqG80Y2l92mODVd4AS Nw2XeBlmYqy3FZSfBPEPxkMaopU6PFZhQfBzdl7aAMlQrC+3hCAV+hPkIQsjieNIJkjp yqjw== X-Forwarded-Encrypted: i=1; AHgh+RoTK86+3bnc+HGimXZDfe7UXBkSxWKfftkBCt/tHg6uribmkMSLQPtcwUZI46f3DYI2HKRqmc1pOjjftFY=@vger.kernel.org X-Gm-Message-State: AFuF++n8tf1654vFcxW0Au3yCPnmuVQalTjmwIPxJLRz36g45E5oVvtw oNakWdc80Cz/3D2B50bqty7DBsDVQsGtJr7zJ5ox+vZz8GxIl7VPWQ6e X-Gm-Gg: AR+sD11Jle07WVgMu4dQHtJWclxQOC3OXfULvtuzgpHiazXP6noIzJyB1OIPgQ2rHlT X39MfB58qbUeIvpiHxXU+R0YnwpyLbLoHfl2P5rANopSp57soutk9O7n61YiG6mLPmzbhXGesmr /3YiRq9uhMXTfXq2C0r8YHSYKtMfeS8hmJjE0zKkLdT9PKZ8gXKhc+swkugFb7UJfQ9DQZ06LfH oV4o+HeK/CBJ44o3jTVp4ZdUAEyMwPw62ybtalmrNqjqg5P+RUTMNwPm9vm692yYk/Ka5MmOmBk ayD0z3WW5hKE3v2jkaCqlnaZJ4ztpHyZ4qltOCNtU1LDfPcBxoxwedQPdaIEPXM70jldnxZaBK/ wLCdUAPMb6sHVbIuiv4injrZH7mEw4R6qeqdY7Y1jPuzrbfiwwX71Fe0A3HV9NLFToSTid3bRg2 gm2wEhWOzqFarfOHuV4WM9IUYG6lnBuTFBAobueMS45nYrZjcgbXAn6j15PdrGyhhhSsKQPTPuC qaEnvKsHE8hES5Uj5FYnAzPBJQXdtdDBYmnmQO3cNA= X-Received: by 2002:a05:6402:538b:b0:698:ecf:d18a with SMTP id 4fb4d7f45d1cf-6a5df6535f1mr9483609a12.9.1787750596381; Wed, 26 Aug 2026 06:23:16 -0700 (PDT) Received: from 1Z10 ([37.163.238.51]) by smtp.gmail.com with ESMTPSA id 4fb4d7f45d1cf-6a5dea83a30sm3633147a12.15.2026.08.26.06.23.14 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 26 Aug 2026 06:23:15 -0700 (PDT) From: Maurizio Casciano To: linux-media@vger.kernel.org Cc: Mauro Carvalho Chehab , Sakari Ailus , Bingbu Cao , Jacopo Mondi , Nicholas Roth , Andy Shevchenko , Hans de Goede , Greg Kroah-Hartman , Jose Maria Martin , linux-staging@lists.linux.dev, linux-kernel@vger.kernel.org, Maurizio Casciano Subject: [PATCH 6/8] media: ov2740: add manual white balance controls Date: Wed, 26 Aug 2026 15:22:54 +0200 Message-ID: <20260826132256.3343451-7-mauriziocasciano7@gmail.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260826132256.3343451-1-mauriziocasciano7@gmail.com> References: <20260826132256.3343451-1-mauriziocasciano7@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The sensor has separate red, green and blue manual white-balance gain registers, but the driver currently writes the same digital-gain value to all three channels. This prevents userspace from correcting the strong color cast of raw Bayer capture. Expose red- and blue-balance controls relative to the digital gain, update all three channels under group hold, and always release and launch the group even when a channel write fails. Tested on the Yoga Book OV2740 with live gain changes and continuous raw capture. Signed-off-by: Maurizio Casciano Assisted-by: Codex:gpt-5.6-sol sparse --- drivers/media/i2c/ov2740.c | 71 +++++++++++++++++++++++++++----------- 1 file changed, 50 insertions(+), 21 deletions(-) diff --git a/drivers/media/i2c/ov2740.c b/drivers/media/i2c/ov2740.c index b760d4dc0e68..7651443b28c1 100644 --- a/drivers/media/i2c/ov2740.c +++ b/drivers/media/i2c/ov2740.c @@ -607,6 +607,9 @@ struct ov2740 { struct v4l2_ctrl *vblank; struct v4l2_ctrl *hblank; struct v4l2_ctrl *exposure; + struct v4l2_ctrl *digital_gain; + struct v4l2_ctrl *red_balance; + struct v4l2_ctrl *blue_balance; =20 /* GPIOs, clocks, regulators */ struct gpio_desc *reset_gpio; @@ -736,35 +739,46 @@ static int ov2740_identify_module(struct ov2740 *ov27= 40) return 0; } =20 -static int ov2740_update_digital_gain(struct ov2740 *ov2740, u32 d_gain) +static int ov2740_update_mwb_gains(struct ov2740 *ov2740) { - int ret; + u32 green_gain =3D ov2740->digital_gain->val; + u32 red_gain, blue_gain; + int end_ret, launch_ret, ret; + + /* Balance controls use 1024 as unity relative to the digital gain. */ + red_gain =3D min_t(u64, + DIV_ROUND_CLOSEST_ULL((u64)green_gain * + ov2740->red_balance->val, + OV2740_DGTL_GAIN_DEFAULT), + OV2740_DGTL_GAIN_MAX); + blue_gain =3D min_t(u64, + DIV_ROUND_CLOSEST_ULL((u64)green_gain * + ov2740->blue_balance->val, + OV2740_DGTL_GAIN_DEFAULT), + OV2740_DGTL_GAIN_MAX); =20 ret =3D ov2740_write_reg(ov2740, OV2740_REG_GROUP_ACCESS, 1, OV2740_GROUP_HOLD_START); if (ret) return ret; =20 - ret =3D ov2740_write_reg(ov2740, OV2740_REG_MWB_R_GAIN, 2, d_gain); + ret =3D ov2740_write_reg(ov2740, OV2740_REG_MWB_R_GAIN, 2, red_gain); if (ret) - return ret; + goto release_group; =20 - ret =3D ov2740_write_reg(ov2740, OV2740_REG_MWB_G_GAIN, 2, d_gain); + ret =3D ov2740_write_reg(ov2740, OV2740_REG_MWB_G_GAIN, 2, green_gain); if (ret) - return ret; + goto release_group; =20 - ret =3D ov2740_write_reg(ov2740, OV2740_REG_MWB_B_GAIN, 2, d_gain); - if (ret) - return ret; + ret =3D ov2740_write_reg(ov2740, OV2740_REG_MWB_B_GAIN, 2, blue_gain); =20 - ret =3D ov2740_write_reg(ov2740, OV2740_REG_GROUP_ACCESS, 1, - OV2740_GROUP_HOLD_END); - if (ret) - return ret; +release_group: + end_ret =3D ov2740_write_reg(ov2740, OV2740_REG_GROUP_ACCESS, 1, + OV2740_GROUP_HOLD_END); + launch_ret =3D ov2740_write_reg(ov2740, OV2740_REG_GROUP_ACCESS, 1, + OV2740_GROUP_HOLD_LAUNCH); =20 - ret =3D ov2740_write_reg(ov2740, OV2740_REG_GROUP_ACCESS, 1, - OV2740_GROUP_HOLD_LAUNCH); - return ret; + return ret ?: end_ret ?: launch_ret; } =20 static int ov2740_test_pattern(struct ov2740 *ov2740, u32 pattern) @@ -805,7 +819,9 @@ static int ov2740_set_ctrl(struct v4l2_ctrl *ctrl) break; =20 case V4L2_CID_DIGITAL_GAIN: - ret =3D ov2740_update_digital_gain(ov2740, ctrl->val); + case V4L2_CID_RED_BALANCE: + case V4L2_CID_BLUE_BALANCE: + ret =3D ov2740_update_mwb_gains(ov2740); break; =20 case V4L2_CID_EXPOSURE: @@ -846,7 +862,7 @@ static int ov2740_init_controls(struct ov2740 *ov2740) int ret; =20 ctrl_hdlr =3D &ov2740->ctrl_handler; - ret =3D v4l2_ctrl_handler_init(ctrl_hdlr, 10); + ret =3D v4l2_ctrl_handler_init(ctrl_hdlr, 12); if (ret) return ret; =20 @@ -881,9 +897,22 @@ static int ov2740_init_controls(struct ov2740 *ov2740) v4l2_ctrl_new_std(ctrl_hdlr, &ov2740_ctrl_ops, V4L2_CID_ANALOGUE_GAIN, OV2740_ANAL_GAIN_MIN, OV2740_ANAL_GAIN_MAX, OV2740_ANAL_GAIN_STEP, OV2740_ANAL_GAIN_MIN); - v4l2_ctrl_new_std(ctrl_hdlr, &ov2740_ctrl_ops, V4L2_CID_DIGITAL_GAIN, - OV2740_DGTL_GAIN_MIN, OV2740_DGTL_GAIN_MAX, - OV2740_DGTL_GAIN_STEP, OV2740_DGTL_GAIN_DEFAULT); + ov2740->digital_gain =3D + v4l2_ctrl_new_std(ctrl_hdlr, &ov2740_ctrl_ops, + V4L2_CID_DIGITAL_GAIN, + OV2740_DGTL_GAIN_MIN, OV2740_DGTL_GAIN_MAX, + OV2740_DGTL_GAIN_STEP, + OV2740_DGTL_GAIN_DEFAULT); + ov2740->red_balance =3D + v4l2_ctrl_new_std(ctrl_hdlr, &ov2740_ctrl_ops, + V4L2_CID_RED_BALANCE, + 1, OV2740_DGTL_GAIN_MAX, 1, + OV2740_DGTL_GAIN_DEFAULT); + ov2740->blue_balance =3D + v4l2_ctrl_new_std(ctrl_hdlr, &ov2740_ctrl_ops, + V4L2_CID_BLUE_BALANCE, + 1, OV2740_DGTL_GAIN_MAX, 1, + OV2740_DGTL_GAIN_DEFAULT); exposure_max =3D ov2740->cur_mode->vts_def - OV2740_EXPOSURE_MAX_MARGIN; ov2740->exposure =3D v4l2_ctrl_new_std(ctrl_hdlr, &ov2740_ctrl_ops, V4L2_CID_EXPOSURE, --=20 2.53.0 From nobody Mon Sep 28 04:55:37 2026 Received: from mail-ed1-f48.google.com (mail-ed1-f48.google.com [209.85.208.48]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id AFBFC4248DC for ; Wed, 26 Aug 2026 13:23:21 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.208.48 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787750608; cv=none; b=mdNskewCiqJB563+ML/S4cwq3YhGvXRYGBqt6WHSsvqT5NocCZmDb7t6k4kzqV2EM0sGbOifPxsAJIZKGCdjM2eZ1mVHb4eDcnXov5VdSg13qOwXfKsr1xM0et4A8i5K3JTEQ5DGwqUgZDG1WhzjFtVCTnq47Z6Xm6ETTseDVHs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787750608; c=relaxed/simple; bh=NUyFjKb1yUUuxtBJbcuPJ4siECfjk98r6Wdhsi921mo=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=XgkObsyDfflxnu7JAgeKEPzXWc/7VNegkpY71+j7fUSIa1554nmheSX6dTWj9wV106Ppp00/xrSGiYus9ycVGq3CTvWzHQzavO6nxfnc84qpTborkpzfspuAw9XqOPkBjHzUjOxgxLogbE1zkjLLoWwO3m+lUo9eXJDQ8lNl4l0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=FV7hkAr5; arc=none smtp.client-ip=209.85.208.48 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="FV7hkAr5" Received: by mail-ed1-f48.google.com with SMTP id 4fb4d7f45d1cf-6a10d02ff43so1270714a12.0 for ; Wed, 26 Aug 2026 06:23:21 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1787750598; x=1788355398; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=gT6oHl5fAdL/6qqxz6ZMerR7vYW0T8hvLKXs7O+hHbI=; b=FV7hkAr5JuEBXgzavr3kgEBBrfc2uBn0y/MJW/uB4dV9DHnkSV+qo6BTEHV33BY8PW P5BQWcAfkY+WEqd6ndWIIy5wb3PKUeSMZIV3xqbxT9RRE5WRwpTJD7EtwZSmn+4Qu1/q hZZ1qFMLnPovat7FdUWMLvqftxlqcxVRv18t52a97Mle1PpNHT772eT8cbJHCAXPLOdD FdsBIGv9OxdbwEQq95HHf8DkHiUO02V3Gn/qGj0wGdEDdKNodtblJYtEgkIPbg+Ad7nI PkAz4rzpSxELZzdMRqId/E9k7kwnf5DWh4yCPBp8d8/PCmTyfrv0/4KphVk46IbLk1nG a6pg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1787750598; x=1788355398; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=gT6oHl5fAdL/6qqxz6ZMerR7vYW0T8hvLKXs7O+hHbI=; b=J9IYk4X2Ld2T+/GiqvpWIJkA2Fsx13q4s6xK/ZlNRkl1Jg0e2lFTEyELIyA8rpg8EI T4LhFwnaEBh8iGIwRXY8dBW6AhlvbOkwzOeRk+5uoBYjR2Gnmu3Vr7PoceL+Qn1v3Bmd M5b4ksSXwMH9cQV+1AySAt38IAjkpt9RmSH13eY4xY3O45hSqji/KLFKmPs1SlaxvvBB n/7yIMAm1XygJK85jX/NZzk5t8emBN48nVC+Ke7kairjB1mOS8xr3Y5Ldyiql4edye5O T21hqyb6CdhdnAbW73bI4JrZxO1gw/g9JGAM42fZqF8s7+yFd+dr2rUyBSeLryW26zl1 YIrg== X-Forwarded-Encrypted: i=1; AHgh+Rom4uoJ2woyW1AjiRF5Ed2yKdA1qMc73/MZFESejs62VF8TjmwI/nIRXA7wqBIcMe2XJsktTnEmc0nu+v0=@vger.kernel.org X-Gm-Message-State: AFuF++lHjhUJYB2PCDUdDQ+/ys9qUB/SYgnVZedIBu8V9OAjXwra/PHx RsTI0Xfd/i3UraSZo8TddGpOZ2F+AvHMRONkn3+7RjfWCMcEwATdx0tJ X-Gm-Gg: AR+sD10FYjLibRPBeVxlSKXTDpZw1aXFnzJaXh07Tqkl3myg/pNAEDRnkGh1x0ojqyL 4hvaTyqh19mOI9RgRqbIEw/GjghtfqE/gcRaRZ9Aomxy03/KSfUIpiIbBF8zaRIbancMeELq27N STN339tKsH9rhfG+IBloRAgrR6seK6t49MVDpjhONGJ34uyW8SBXk1dfPS67rpWwI4IgLDhzKib J+eji4HubTZ4DEtG8fel91ixJDoPu9l5c/U/PLc+x/QcBFLPEWgTZ92ycEQ3xjC5O2ZAhy9R3GV 7mB4NySnU9/aJAiNOfCAEZN5M5Ef0YK/KmSzDa2XTJYEVulizOLeGZU+KysoiD0MxUAXes/a8BE fuL2CrNGhzZH736xEDC2AjsN227UBvuY0rPHpz63OozMv1r71kOiBK7/SaWy2bJC7RVYFGuxTRD ltB8F0qbHg/qOCbwMksHFQqKotUeWbBHHmii8CQYQGtKhY0oZiArRZ2IM2RiPQnhh34F3AVjiTv l531WAT+03Rr3vIeVyJXUwgsrObbvShlVuWAcTy+tk= X-Received: by 2002:a05:6402:2490:b0:6a5:d8eb:da01 with SMTP id 4fb4d7f45d1cf-6a5df31ac64mr9983196a12.0.1787750598390; Wed, 26 Aug 2026 06:23:18 -0700 (PDT) Received: from 1Z10 ([37.163.238.51]) by smtp.gmail.com with ESMTPSA id 4fb4d7f45d1cf-6a5dea83a30sm3633147a12.15.2026.08.26.06.23.16 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 26 Aug 2026 06:23:17 -0700 (PDT) From: Maurizio Casciano To: linux-media@vger.kernel.org Cc: Mauro Carvalho Chehab , Sakari Ailus , Bingbu Cao , Jacopo Mondi , Nicholas Roth , Andy Shevchenko , Hans de Goede , Greg Kroah-Hartman , Jose Maria Martin , linux-staging@lists.linux.dev, linux-kernel@vger.kernel.org, Maurizio Casciano Subject: [PATCH 7/8] media: atomisp: allow opt-in raw Bayer capture Date: Wed, 26 Aug 2026 15:22:55 +0200 Message-ID: <20260826132256.3343451-8-mauriziocasciano7@gmail.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260826132256.3343451-1-mauriziocasciano7@gmail.com> References: <20260826132256.3343451-1-mauriziocasciano7@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" AtomISP currently rejects all raw formats and silently substitutes YUV420. This prevents userspace camera processing stacks from obtaining unprocessed sensor frames. Add an allow_raw_output module parameter, disabled by default. When it is enabled, enumerate only the raw format matching the sensor media-bus code and reconcile raw format requests with the code selected by the sensor. Also apply the per-sensor padding discovered by the CSI-2 bridge when enumerating and negotiating frame sizes. Existing systems retain the global padding and raw-output defaults. Tested on a Lenovo Yoga Book YB1-X91L with raw capture from its OV2740 and OV8858 sensors. Signed-off-by: Maurizio Casciano Assisted-by: Codex:gpt-5.6-sol sparse --- .../staging/media/atomisp/pci/atomisp_cmd.c | 24 ++++++++++++++----- .../media/atomisp/pci/atomisp_internal.h | 6 +++++ .../staging/media/atomisp/pci/atomisp_ioctl.c | 13 ++++++---- .../staging/media/atomisp/pci/atomisp_v4l2.c | 15 ++++++++++++ 4 files changed, 48 insertions(+), 10 deletions(-) diff --git a/drivers/staging/media/atomisp/pci/atomisp_cmd.c b/drivers/stag= ing/media/atomisp/pci/atomisp_cmd.c index 6cd500d9fd26..9e6387b662bc 100644 --- a/drivers/staging/media/atomisp/pci/atomisp_cmd.c +++ b/drivers/staging/media/atomisp/pci/atomisp_cmd.c @@ -3572,10 +3572,14 @@ void atomisp_get_padding(struct atomisp_device *isp= , u32 width, u32 height, u32 min_pad_w =3D ISP2400_MIN_PAD_W; u32 min_pad_h =3D ISP2400_MIN_PAD_H; struct v4l2_mbus_framefmt *sink; + u32 input_padding_w =3D input->padding_override ? + input->padding_w : pad_w; + u32 input_padding_h =3D input->padding_override ? + input->padding_h : pad_h; =20 if (!input->crop_support) { - *padding_w =3D pad_w; - *padding_h =3D pad_h; + *padding_w =3D input_padding_w; + *padding_h =3D input_padding_h; return; } =20 @@ -3588,8 +3592,10 @@ void atomisp_get_padding(struct atomisp_device *isp,= u32 width, u32 height, native_rect.height /=3D 2; } =20 - *padding_w =3D min_t(u32, (native_rect.width - width) & ~1, pad_w); - *padding_h =3D min_t(u32, (native_rect.height - height) & ~1, pad_h); + *padding_w =3D min_t(u32, (native_rect.width - width) & ~1, + input_padding_w); + *padding_h =3D min_t(u32, (native_rect.height - height) & ~1, + input_padding_h); =20 /* The below minimum padding requirements are for BYT / ISP2400 only */ if (IS_ISP2401) @@ -3804,8 +3810,9 @@ int atomisp_try_fmt(struct atomisp_device *isp, struc= t v4l2_pix_format *f, int ret; =20 fmt =3D atomisp_get_format_bridge(f->pixelformat); - /* Currently, raw formats are broken!!! */ - if (!fmt || fmt->sh_fmt =3D=3D IA_CSS_FRAME_FORMAT_RAW) { + /* Raw output remains opt-in while the legacy CSS path is validated. */ + if (!fmt || (fmt->sh_fmt =3D=3D IA_CSS_FRAME_FORMAT_RAW && + !atomisp_allow_raw_output)) { f->pixelformat =3D V4L2_PIX_FMT_YUV420; =20 fmt =3D atomisp_get_format_bridge(f->pixelformat); @@ -3846,6 +3853,11 @@ int atomisp_try_fmt(struct atomisp_device *isp, stru= ct v4l2_pix_format *f, ffmt.code); return -EINVAL; } + if (fmt->sh_fmt =3D=3D IA_CSS_FRAME_FORMAT_RAW && + fmt->mbus_code !=3D snr_fmt->mbus_code) { + fmt =3D snr_fmt; + f->pixelformat =3D fmt->pixelformat; + } =20 f->width =3D ffmt.width - padding_w; f->height =3D ffmt.height - padding_h; diff --git a/drivers/staging/media/atomisp/pci/atomisp_internal.h b/drivers= /staging/media/atomisp/pci/atomisp_internal.h index 5a69580b8251..99a55297033e 100644 --- a/drivers/staging/media/atomisp/pci/atomisp_internal.h +++ b/drivers/staging/media/atomisp/pci/atomisp_internal.h @@ -98,6 +98,9 @@ #define ATOMISP_CSS_SUPPORT_YUVPP 1 =20 #define ATOMISP_CSS_OUTPUT_SECOND_INDEX 1 + +extern bool atomisp_allow_raw_output; + #define ATOMISP_CSS_OUTPUT_DEFAULT_INDEX 0 =20 /* ISP2401 */ @@ -116,6 +119,9 @@ struct atomisp_input_subdev { enum atomisp_camera_port port; u32 code; /* MEDIA_BUS_FMT_* */ + u32 padding_w; + u32 padding_h; + bool padding_override; bool binning_support; bool crop_support; bool sensor_on; diff --git a/drivers/staging/media/atomisp/pci/atomisp_ioctl.c b/drivers/st= aging/media/atomisp/pci/atomisp_ioctl.c index 50366bf10f32..e63b3e99e5fd 100644 --- a/drivers/staging/media/atomisp/pci/atomisp_ioctl.c +++ b/drivers/staging/media/atomisp/pci/atomisp_ioctl.c @@ -554,8 +554,10 @@ static int atomisp_enum_framesizes(struct file *file, = void *priv, return ret; =20 fsize->type =3D V4L2_FRMSIZE_TYPE_DISCRETE; - fsize->discrete.width =3D fse.max_width - pad_w; - fsize->discrete.height =3D fse.max_height - pad_h; + fsize->discrete.width =3D fse.max_width - + (input->padding_override ? input->padding_w : pad_w); + fsize->discrete.height =3D fse.max_height - + (input->padding_override ? input->padding_h : pad_h); =20 return 0; } @@ -629,8 +631,11 @@ static int atomisp_enum_fmt_cap(struct file *file, voi= d *fh, * * FIXME: fix the pipeline to allow sensor format too. */ - if (format->sh_fmt =3D=3D IA_CSS_FRAME_FORMAT_RAW) - continue; + if (format->sh_fmt =3D=3D IA_CSS_FRAME_FORMAT_RAW) { + if (!atomisp_allow_raw_output || + format->mbus_code !=3D code.code) + continue; + } =20 /* Found a match. Now let's pick f->index'th one. */ if (fi < f->index) { diff --git a/drivers/staging/media/atomisp/pci/atomisp_v4l2.c b/drivers/sta= ging/media/atomisp/pci/atomisp_v4l2.c index 812230397409..d30f69f5a794 100644 --- a/drivers/staging/media/atomisp/pci/atomisp_v4l2.c +++ b/drivers/staging/media/atomisp/pci/atomisp_v4l2.c @@ -25,6 +25,7 @@ =20 #include "atomisp_cmd.h" #include "atomisp_common.h" +#include "atomisp_csi2.h" #include "atomisp_fops.h" #include "atomisp_ioctl.h" #include "atomisp_internal.h" @@ -72,6 +73,11 @@ int pad_h =3D 16; module_param(pad_h, int, 0644); MODULE_PARM_DESC(pad_h, "extra data for ISP processing"); =20 +bool atomisp_allow_raw_output; +module_param_named(allow_raw_output, atomisp_allow_raw_output, bool, 0644); +MODULE_PARM_DESC(allow_raw_output, + "allow experimental raw Bayer output (default:false)"); + /* * FIXME: this is a hack to make easier to support ISP2401 variant. * As a given system will either be ISP2401 or not, we can just use @@ -889,6 +895,15 @@ static void atomisp_init_sensor(struct atomisp_input_s= ubdev *input) struct v4l2_subdev_state *try_sd_state, *act_sd_state; int i, err; =20 + input->padding_override =3D + atomisp_csi2_get_sensor_padding(input->sensor->dev, + &input->padding_w, + &input->padding_h); + if (input->padding_override) + dev_info(input->sensor->dev, + "using ISP input padding %ux%u\n", + input->padding_w, input->padding_h); + /* * FIXME: Drivers are not supposed to use __v4l2_subdev_state_alloc() * but atomisp needs this for try_fmt on its /dev/video# node since --=20 2.53.0 From nobody Mon Sep 28 04:55:37 2026 Received: from mail-ed1-f46.google.com (mail-ed1-f46.google.com [209.85.208.46]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 31D7242CB14 for ; Wed, 26 Aug 2026 13:23:23 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.208.46 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787750610; cv=none; b=Xfv9vU2sZZIiHrPLVvZ/4KsihoNFekMOAjKA6h3O+oYEvc98bh9bp+AGvCIV7HwIukgCNnEJpGz9e3KIa7VV8ac7tHFMbDrJeO2yYR5UKrC9Vsv/v2xfx7PP7P00GR3UaJ116+isRSpgOQq6NvwAjP3yg45EuJtEY3ukKAMYfx8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787750610; c=relaxed/simple; bh=XRXlwQynmoDkSnN+1aeMbXNgIHZRxzQz4EGF3JDpdMk=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=n3NIwf2DUZ74OGliOMCgabG0Wsdd4g+aPbun54uDiTtZKKPyIHdSAgSnyN/LhbixIGNjJ3rtFQhfTuaXC2nGil0J8jlGBUCGaXYff0nsj2OxL25Wm4qwB7AgRWFbj44aiNUGO46fV6EgWZ3znqf6l24SJKhW8U9QkkDRAAx7j2I= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=Jp9GYdb0; arc=none smtp.client-ip=209.85.208.46 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="Jp9GYdb0" Received: by mail-ed1-f46.google.com with SMTP id 4fb4d7f45d1cf-6a374bea882so1188584a12.1 for ; Wed, 26 Aug 2026 06:23:22 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1787750600; x=1788355400; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=AKB/xr2aOCbOg329ehvyXjbYABzeMuLJuajYHAFNU6k=; b=Jp9GYdb08aUSX5x7TKPUDAwhR6Yd/eB6eBPK84TVefqLGFH4VgR1a+2+x7nW1EvkE3 zXYXlzbbpbI6jC/3gzBnXJ/vWwzHe60NunDeZgRxDQfWnjNgHgQ/TZHRF7C3COfaWCrL KQOQw1pDfQXMp14nnt3WZttBbCtXYCuOjH7OYGJluewyg8qv097yrWEu1vRrIMzD7OT0 WQ1+3rjUuTQtPWhnEr7Gx881nbejKn7FiUjTjHW3XKOzONlFFG07hCowKmmEOXibIqWp ydSQKxhPq/lSzCgN6FQGWSs9GUwPdMg2EP8dzx6hxcSFaDQ7Qx2yEe70yXLCZa4wlbLT hBIw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1787750600; x=1788355400; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=AKB/xr2aOCbOg329ehvyXjbYABzeMuLJuajYHAFNU6k=; b=l9PirvZx1lSrnGT8KQUNrTJSdvujjYCvvtdWzZIr+xepS7tT/3k5XAx7Xk3HP1XBCg odHovehrwoRaOrYcVPi2MTk98pXmUb8tIlbGLyjtdh3s8jEGCwmdLagVRni3gnudYjEP MSkFasIavvHnJ5BIayzSMK++qNR1+tVCHIU3rRpwVAnPPk7vFUR5jMzJQKKnx80zHrg8 ip4V2mC6RE4ylOBwo4gns+TxMAHOSmtGN89S1Xw5urXOWjgSiCN4LE4DW0Jl8KTQQKg+ PcoV2dctlbjGDkmgrYo7gbBn/FX7JAY8WuOpvJ0En7gkYU+5X1/tCab/7EGBFcSaseBP clkw== X-Forwarded-Encrypted: i=1; AHgh+Rq2dytfu/AqrJkf2gQcx3zKmwFvlx/zNZmqCw7Ncn0mkJiG6hMupKn3FGeVcIMUeLMW8IlBfgv8tzKgWu0=@vger.kernel.org X-Gm-Message-State: AFuF++mi9Q2T+b27ENLqxEGT0EQnIK/zqK8WFlCva4IUAas/e1ZtwEKm 05YJCMSAOSIR03+pB++6Xmoyuk7/i04BbuswJTkFiwnTkRWDxIIxx1p1 X-Gm-Gg: AR+sD13/T1elItRfcg3Re3o3AVvpcOp1+vWzOcbPYDiZ/vedKyptbeyryuLkDeELVOr PtgMHiixTASIGsdfkQ14RNCw9ctjP19Vtkn4bFggMjdCTl5QSC89oLJMDYnKrFWx+cveF+ZOJFp xsXdgtivFvgGyZcVSxUFbx+P+s6h30oeM2sSGvjIOb1XbWkfVU5usOM9TA1xR5NqLJo0RbOPmyp QQ21Hm110Z/H7xFgr4ReqCur+qadvmzKI3IRJteOluTG+FXobYup6EWnxfaStXT59BqZxq9ECJ6 ODIqk1yc7WMYZ4pai6dQ5hb8M08887+69YMzcAQq1dvQLE3qRTqps+/UFeHRPLqyReYbEASVTdx VjG1WWMkHNuyG2S+n9josER3rWuWBoMqZgmcBNWqZnrhn7y+inKv9YstypqRdOhxMDZu7+oA/Gv LDGSajjx0oxHdg4eiO+XrnqOtWmW0TRB+95zyRYJATyHMpya1GQyaDAaLklbRFo3U+1of/UYwaV r7eRyMyJsZNelGUOIo5rfF6DUxicc6+9v8EgwBPNtY= X-Received: by 2002:a05:6402:3245:b0:698:c13e:179a with SMTP id 4fb4d7f45d1cf-6a5df653615mr8508421a12.10.1787750600453; Wed, 26 Aug 2026 06:23:20 -0700 (PDT) Received: from 1Z10 ([37.163.238.51]) by smtp.gmail.com with ESMTPSA id 4fb4d7f45d1cf-6a5dea83a30sm3633147a12.15.2026.08.26.06.23.18 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 26 Aug 2026 06:23:19 -0700 (PDT) From: Maurizio Casciano To: linux-media@vger.kernel.org Cc: Mauro Carvalho Chehab , Sakari Ailus , Bingbu Cao , Jacopo Mondi , Nicholas Roth , Andy Shevchenko , Hans de Goede , Greg Kroah-Hartman , Jose Maria Martin , linux-staging@lists.linux.dev, linux-kernel@vger.kernel.org, Maurizio Casciano Subject: [PATCH 8/8] media: i2c: Add WV517S lens actuator driver Date: Wed, 26 Aug 2026 15:22:56 +0200 Message-ID: <20260826132256.3343451-9-mauriziocasciano7@gmail.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260826132256.3343451-1-mauriziocasciano7@gmail.com> References: <20260826132256.3343451-1-mauriziocasciano7@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The Lenovo Yoga Book YB1-X91 rear camera contains a WV517S voice-coil actuator. Add a V4L2 lens subdevice exposing the standard 10-bit FOCUS_ABSOLUTE control and the device ringing-control mode. Tie register access to runtime PM so the IPU bridge sensor link keeps shared power resources active. Propagate PM acquisition failures and restore the drive mode and requested focus position after resume. The register addresses and drive-mode value are derived from Intel's GPL-2.0 WV517 driver. Retain its copyright notice. Link: https://github.com/jekhor/yogabook-linux-android-kernel/blob/574bae69= 2716f1b14093497bfab8a007fe8e460b/drivers/external_drivers/camera/drivers/me= dia/i2c/wv517.c Signed-off-by: Maurizio Casciano Assisted-by: Codex:gpt-5.6-sol sparse --- MAINTAINERS | 1 + drivers/media/i2c/Kconfig | 8 ++ drivers/media/i2c/Makefile | 1 + drivers/media/i2c/wv517s.c | 199 +++++++++++++++++++++++++++++++++++++ 4 files changed, 209 insertions(+) create mode 100644 drivers/media/i2c/wv517s.c diff --git a/MAINTAINERS b/MAINTAINERS index 3785b8c1de0a..205a42646a7d 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -28268,6 +28268,7 @@ S: Maintained F: drivers/media/i2c/ak* F: drivers/media/i2c/dw* F: drivers/media/i2c/lm* +F: drivers/media/i2c/wv517s.c =20 V4L2 CAMERA SENSOR DRIVERS M: Sakari Ailus diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig index 5c52007f9cbe..c488452c1b38 100644 --- a/drivers/media/i2c/Kconfig +++ b/drivers/media/i2c/Kconfig @@ -949,6 +949,14 @@ config VIDEO_DW9807_VCM capability. This is designed for linear control of voice coil motors, controlled via I2C serial interface. =20 +config VIDEO_WV517S + tristate "WV517S lens voice coil support" + help + This is a driver for the WV517S camera lens voice coil. It supports + the 10-bit focus control used by the Lenovo Yoga Book rear camera. + The driver exposes the actuator through the standard V4L2 lens + sub-device interface. + endif =20 menu "Flash devices" diff --git a/drivers/media/i2c/Makefile b/drivers/media/i2c/Makefile index d04bd5724552..e480932a9540 100644 --- a/drivers/media/i2c/Makefile +++ b/drivers/media/i2c/Makefile @@ -173,4 +173,5 @@ obj-$(CONFIG_VIDEO_VP27SMPX) +=3D vp27smpx.o obj-$(CONFIG_VIDEO_VPX3220) +=3D vpx3220.o obj-$(CONFIG_VIDEO_WM8739) +=3D wm8739.o obj-$(CONFIG_VIDEO_WM8775) +=3D wm8775.o +obj-$(CONFIG_VIDEO_WV517S) +=3D wv517s.o obj-$(CONFIG_VIDEO_INTEL_CVS) +=3D cvs/ diff --git a/drivers/media/i2c/wv517s.c b/drivers/media/i2c/wv517s.c new file mode 100644 index 000000000000..43d15aadea30 --- /dev/null +++ b/drivers/media/i2c/wv517s.c @@ -0,0 +1,199 @@ +// SPDX-License-Identifier: GPL-2.0-only + +/* + * WV517S voice-coil motor driver + * + * Copyright (c) 2014 Intel Corporation. + * + * On the Lenovo Yoga Book the IPU bridge instantiates this actuator as a + * secondary I2C client of the rear camera. The bridge holds the sensor's + * shared power resources on while probing the actuator and adds a runtime= -PM + * device link for subsequent accesses. + */ + +#include +#include +#include + +#include +#include + +#define WV517S_MAX_FOCUS_POSITION 1023 +#define WV517S_DEFAULT_FOCUS_POSITION 300 + +#define WV517S_REG_FOCUS 0x41 +#define WV517S_REG_DRIVE_MODE 0x43 +#define WV517S_DRIVE_MODE_12_6_MS 0x0211 + +struct wv517s_device { + struct v4l2_ctrl_handler ctrl_handler; + struct v4l2_subdev sd; + struct v4l2_ctrl *focus; +}; + +static inline struct wv517s_device *to_wv517s(struct v4l2_subdev *sd) +{ + return container_of(sd, struct wv517s_device, sd); +} + +static int wv517s_write(struct i2c_client *client, u8 reg, u16 value) +{ + u8 buf[] =3D { reg, value >> 8, value }; + int ret; + + ret =3D i2c_master_send(client, buf, sizeof(buf)); + if (ret < 0) + return ret; + + return ret =3D=3D sizeof(buf) ? 0 : -EIO; +} + +static int wv517s_set_ctrl(struct v4l2_ctrl *ctrl) +{ + struct wv517s_device *wv517s =3D container_of(ctrl->handler, + struct wv517s_device, + ctrl_handler); + struct i2c_client *client =3D v4l2_get_subdevdata(&wv517s->sd); + int ret; + + ret =3D pm_runtime_get_if_in_use(&client->dev); + if (ret <=3D 0) + return ret; + + if (ctrl->id =3D=3D V4L2_CID_FOCUS_ABSOLUTE) + ret =3D wv517s_write(client, WV517S_REG_FOCUS, ctrl->val); + else + ret =3D -EINVAL; + + pm_runtime_put(&client->dev); + + return ret; +} + +static const struct v4l2_ctrl_ops wv517s_ctrl_ops =3D { + .s_ctrl =3D wv517s_set_ctrl, +}; + +static int wv517s_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) +{ + return pm_runtime_resume_and_get(sd->dev); +} + +static int wv517s_close(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) +{ + pm_runtime_put(sd->dev); + + return 0; +} + +static const struct v4l2_subdev_internal_ops wv517s_internal_ops =3D { + .open =3D wv517s_open, + .close =3D wv517s_close, +}; + +static const struct v4l2_subdev_ops wv517s_subdev_ops =3D { }; + +static int wv517s_resume(struct device *dev) +{ + struct v4l2_subdev *sd =3D dev_get_drvdata(dev); + struct wv517s_device *wv517s =3D to_wv517s(sd); + struct i2c_client *client =3D to_i2c_client(dev); + int ret; + + /* Restore the vendor-recommended 12.6 ms ringing-control mode. */ + ret =3D wv517s_write(client, WV517S_REG_DRIVE_MODE, + WV517S_DRIVE_MODE_12_6_MS); + if (ret) + return ret; + + return wv517s_write(client, WV517S_REG_FOCUS, wv517s->focus->val); +} + +static int wv517s_probe(struct i2c_client *client) +{ + struct wv517s_device *wv517s; + int ret; + + wv517s =3D devm_kzalloc(&client->dev, sizeof(*wv517s), GFP_KERNEL); + if (!wv517s) + return -ENOMEM; + + v4l2_i2c_subdev_init(&wv517s->sd, client, &wv517s_subdev_ops); + wv517s->sd.flags |=3D V4L2_SUBDEV_FL_HAS_DEVNODE; + wv517s->sd.internal_ops =3D &wv517s_internal_ops; + wv517s->sd.entity.function =3D MEDIA_ENT_F_LENS; + + v4l2_ctrl_handler_init(&wv517s->ctrl_handler, 1); + wv517s->focus =3D v4l2_ctrl_new_std(&wv517s->ctrl_handler, + &wv517s_ctrl_ops, + V4L2_CID_FOCUS_ABSOLUTE, 0, + WV517S_MAX_FOCUS_POSITION, 1, + WV517S_DEFAULT_FOCUS_POSITION); + if (wv517s->ctrl_handler.error) { + ret =3D wv517s->ctrl_handler.error; + goto err_free_ctrl_handler; + } + wv517s->sd.ctrl_handler =3D &wv517s->ctrl_handler; + + ret =3D media_entity_pads_init(&wv517s->sd.entity, 0, NULL); + if (ret) + goto err_free_ctrl_handler; + + ret =3D wv517s_resume(&client->dev); + if (ret) + goto err_cleanup_entity; + + pm_runtime_set_active(&client->dev); + pm_runtime_enable(&client->dev); + + ret =3D v4l2_async_register_subdev(&wv517s->sd); + if (ret) + goto err_disable_pm; + + pm_runtime_idle(&client->dev); + + return 0; + +err_disable_pm: + pm_runtime_disable(&client->dev); +err_cleanup_entity: + media_entity_cleanup(&wv517s->sd.entity); +err_free_ctrl_handler: + v4l2_ctrl_handler_free(&wv517s->ctrl_handler); + + return ret; +} + +static void wv517s_remove(struct i2c_client *client) +{ + struct v4l2_subdev *sd =3D i2c_get_clientdata(client); + struct wv517s_device *wv517s =3D to_wv517s(sd); + + v4l2_async_unregister_subdev(sd); + pm_runtime_disable(&client->dev); + v4l2_ctrl_handler_free(&wv517s->ctrl_handler); + media_entity_cleanup(&sd->entity); +} + +static const struct i2c_device_id wv517s_id_table[] =3D { + { "wv517s" }, + { } +}; +MODULE_DEVICE_TABLE(i2c, wv517s_id_table); + +static DEFINE_RUNTIME_DEV_PM_OPS(wv517s_pm_ops, NULL, wv517s_resume, NULL); + +static struct i2c_driver wv517s_i2c_driver =3D { + .driver =3D { + .name =3D "wv517s", + .pm =3D pm_ptr(&wv517s_pm_ops), + }, + .probe =3D wv517s_probe, + .remove =3D wv517s_remove, + .id_table =3D wv517s_id_table, +}; +module_i2c_driver(wv517s_i2c_driver); + +MODULE_AUTHOR("Maurizio Casciano"); +MODULE_DESCRIPTION("WV517S VCM driver"); +MODULE_LICENSE("GPL"); --=20 2.53.0