From nobody Tue Apr 7 14:07:40 2026 Received: from mail-wm1-f45.google.com (mail-wm1-f45.google.com [209.85.128.45]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9E2F93D7D9D for ; Wed, 25 Feb 2026 15:11:37 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.45 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772032299; cv=none; b=aP5UkpIeNg4V0zx8X7t/WuWIT5TUmXsRCmR4ufcgufJ4+hi9Y2d+FrnTsGVUSmpZ9T1DaDTRguTbyatl5/tt9zuiQ4J5dfRSDhV89fqCbLYqUfmjQhzaaMYCW1JawVVJicCT7FE/T9UsA7WmtmavgWUNgA57DyOuJ8IXnQDqLsA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772032299; c=relaxed/simple; bh=9J+a7zIrcy/zCnWPa4cL2hu++ZOXqEy1OCVn2l4RQdM=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=C+yZCtq4cnPXH3fsoOfP0Mhn6uVWW7D9jGeN9Xp+xeeCWlPAAr+e9+25YXXLeIqPBphBiAxNC3FQIIz2ZMREwhMGyd/uDn8TS4GVB5Dnw/vAO6Bc2uAWNsjdOp+1BQJNkKUdfsykVrqPWFj5bkDHsga2yzGybB43JkoCKcNCN3c= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linaro.org; spf=pass smtp.mailfrom=linaro.org; dkim=pass (2048-bit key) header.d=linaro.org header.i=@linaro.org header.b=mtlzFe+Z; arc=none smtp.client-ip=209.85.128.45 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linaro.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linaro.org header.i=@linaro.org header.b="mtlzFe+Z" Received: by mail-wm1-f45.google.com with SMTP id 5b1f17b1804b1-4807068eacbso53403475e9.2 for ; Wed, 25 Feb 2026 07:11:37 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1772032296; x=1772637096; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=68uLHf8484MA1JM1svwKaCIh8DyHlGyhkbTdY2VJTEQ=; b=mtlzFe+ZLgf/1TAqAOn/s9DWNNPFn2TmqrKcmJBmDaoxKR5eEQTcHNY+GuSrrE1Zt4 BSy0s33dA4AwHUbvtzqFmZwE+sT2MaGDn+RxRMxArh1k3NyIf5LO3osbbnpbvFpXNijR SyUscFeSxOPgai0TBtnvvtSo32RFwAlaDlM2IR97+bbUm+/a1CbmHLV+Zuecd5gXi0BS HVJmNLu5s+sZdmLAzsTlqJIjjTMl2ZBfQlH9Vk3G+YfM2fehY4FKqmQpqaVx4iTYhyTp GVL8aKTVGZfpwl4Xgy1wtX/b0lMBxHxz7L1Zzhs5jDrqvuDTyIz1S0vaAHwJAwExVCGI 7FHA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1772032296; x=1772637096; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=68uLHf8484MA1JM1svwKaCIh8DyHlGyhkbTdY2VJTEQ=; b=MHOxMy5wOsYMYc3an1+4UlU30mUQoBN9VB+nMmssYx+M+aO9oEX0UDAJ8hRs4fMr0+ a1fPl9fObO55+ZKsQ3GIeJqwek+9lWNbuKf4UzZIHhIARmC0H3yEHojlzjSjA0vGtfAV 4Kifjj2YiOLOjs0kKDcybw3cIlpp3tKJ5b46CKIg4QXETJXZRO8pjRzycwdlSqXfVR45 WqZEgOd2kav1VuazkToeEP5AL3bfH9Wx5BHjfyQEVhcNHz0yhx1Q5cANVQti3XAYa/mA v123zaPbSsFF1Hwcw8AfyHYdS7WeSbhmhiZ46cqUIdLkn8qgV2Rvvj8NxrUcswFas244 Jgng== X-Forwarded-Encrypted: i=1; AJvYcCVrUJnc0xytAHDFSOWKzMR7vnnrtQbM7pTssvH8/3jw4QnVvhn1RU1DIZq/2cGaCGhFq+oqGF7KYMTO1GA=@vger.kernel.org X-Gm-Message-State: AOJu0YzsS/+/tburGW+YFiUKHQtk8bHPI6wiXS5td0IsohWFVZ5urL+g DsNN+ZBujP/64ejlxh+veZ7zNIC0YxUkSP/3PT4LV4S2YlglLXCmewn74AexIhp5ljs= X-Gm-Gg: ATEYQzzDNsDYfdHXgP0Etp9bhKGFfLRCN7s4foOC10XBMjyrnyzU/vbKYsHzhg0wz+u VQ8Of4mQlCA7epsRfsGuK2ldv1T0G1wbVc3IE4TnZUQFfNAA0skgtJG++7Xsvw3Hbjhl/I2KpRZ HuJ8qCn7htoDf7QLlyDt91gwcbUGhNHBNqhuGGA5RdXA3EPIox4RUDjE/BTVNpWU8B+/AZVNzkv OyPc7OzL7VZRldGGeDjszaSMFIqS18p2HGMUaUvJ0/x9AWjytDyVn4Gy9MnyClG0z7v3wh2WOyh 2ala4V7urFXw0gCjk5SrCT/1qr7hoBk3lVrF/6gIEtDlXsd6wVIdUdzS0HBFD+TVtRzUmPUqvZy ZJ4OZTT2hoJBudgUeRJkBRoMxUVFTatKmj+E5IELswPJvtZBZeqnkMXo7vfwMMVNN0h2koKAIDR 2Qs5ew91fWRWJnECm8zYQuGEEOoHEeesbcoSCOeQ0coNY8wkz7yB6XySQlZ8YOF1o4 X-Received: by 2002:a05:600c:6291:b0:47a:7fdd:2906 with SMTP id 5b1f17b1804b1-483a95b7157mr285291305e9.12.1772032295810; Wed, 25 Feb 2026 07:11:35 -0800 (PST) Received: from [192.168.0.35] (188-141-3-146.dynamic.upc.ie. [188.141.3.146]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-483bfba9a5esm33950695e9.4.2026.02.25.07.11.34 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 25 Feb 2026 07:11:35 -0800 (PST) From: Bryan O'Donoghue Date: Wed, 25 Feb 2026 15:11:23 +0000 Subject: [PATCH v8 06/18] media: qcom: camss: Add support for PHY API devices Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260225-b4-linux-next-25-03-13-dtsi-x1e80100-camss-v8-6-95517393bcb2@linaro.org> References: <20260225-b4-linux-next-25-03-13-dtsi-x1e80100-camss-v8-0-95517393bcb2@linaro.org> In-Reply-To: <20260225-b4-linux-next-25-03-13-dtsi-x1e80100-camss-v8-0-95517393bcb2@linaro.org> To: Bjorn Andersson , Michael Turquette , Stephen Boyd , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Robert Foss , Todor Tomov , Mauro Carvalho Chehab , Konrad Dybcio , Vladimir Zapolskiy , Bryan O'Donoghue Cc: linux-arm-msm@vger.kernel.org, linux-clk@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-media@vger.kernel.org, Bryan O'Donoghue , Krzysztof Kozlowski X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=15748; i=bryan.odonoghue@linaro.org; h=from:subject:message-id; bh=9J+a7zIrcy/zCnWPa4cL2hu++ZOXqEy1OCVn2l4RQdM=; b=owEBbQKS/ZANAwAKASJxO7Ohjcg6AcsmYgBpnxEasq3dmdIL5sODhWfonAgnhfNAhxR+t0zFR z8hEwQkfZSJAjMEAAEKAB0WIQTmk/sqq6Nt4Rerb7QicTuzoY3IOgUCaZ8RGgAKCRAicTuzoY3I OhaVEACgu1X2A5Vqnnho/YDVUrTorJT9ira8qBvIccOTqZ9/PG7Lheoi+veuxOVybcPwSKRNp6a bMcByF4kNc0BAzpzVu97oLdqee92VLvx4BF3DU379l4VTKYlVMcXQhOVH/octF3j4/d7UJh596a 4s6I94hvZ7M5ZGZKta5nMXYr//0oIINsHbnpbiDTmABUtYpmOP0h1IBpIurXdYVc3QHvwXKHvlM 8kefM5Zuh9dRAZO0IvhBZ/Am0mHeoo8Cza9yzfZE6DtRh9LnnTr9QToZVK+MSZbhSswES3BArNz is2Gc2I/Iq5SKRm297iJa7kuYmo1aJwfgvmQBL6KXmeeQuxd2QXDQt7QxbXUGzFvofjoGMVANsk FryHMZXYBLcMa1EzdQFz/IbjAnlc3QoM+JvcdA2e3/fWF+Y4JrY/abfAuVpwVZ1XXWc9dxMhW8n 86dUZxBQgyjYFjX06HvfxGjm+DRJAYE3Ts1PaABosvaKRc9KeUnT8hZvX3hQtP9f+0S+I6bWw1h iwa914E789fSuz2DxyWT4bBr5zd/XX6QonqgL41Y2snJCVbOtnefO6QsqNcrGisAbod+xRsHeFN fOSYwKWZGrzVKBz5M27/TlXMVpDyI2wvrb8rNfZFdaBv2bS34DUS9ndSzu5zDJm3iuHe8V3JLYw nTiAB5oH2i7bzzg== X-Developer-Key: i=bryan.odonoghue@linaro.org; a=openpgp; fpr=E693FB2AABA36DE117AB6FB422713BB3A18DC83A Add the ability to use a PHY pointer which interacts with the standard PHY API. In the first instance the code will try to use the new PHY interface. If no PHYs are present in the DT then the legacy method will be attempted. Signed-off-by: Bryan O'Donoghue Reviewed-by: Christopher Obbard Tested-by: Christopher Obbard --- drivers/media/platform/qcom/camss/Kconfig | 1 + drivers/media/platform/qcom/camss/camss-csiphy.c | 185 +++++++++++++++++++= ++-- drivers/media/platform/qcom/camss/camss-csiphy.h | 7 + drivers/media/platform/qcom/camss/camss.c | 72 +++++++-- 4 files changed, 235 insertions(+), 30 deletions(-) diff --git a/drivers/media/platform/qcom/camss/Kconfig b/drivers/media/plat= form/qcom/camss/Kconfig index 4eda48cb1adf0..1edc5e5a1829e 100644 --- a/drivers/media/platform/qcom/camss/Kconfig +++ b/drivers/media/platform/qcom/camss/Kconfig @@ -7,3 +7,4 @@ config VIDEO_QCOM_CAMSS select VIDEO_V4L2_SUBDEV_API select VIDEOBUF2_DMA_SG select V4L2_FWNODE + select PHY_QCOM_MIPI_CSI2 diff --git a/drivers/media/platform/qcom/camss/camss-csiphy.c b/drivers/med= ia/platform/qcom/camss/camss-csiphy.c index 62623393f4144..59564284fd270 100644 --- a/drivers/media/platform/qcom/camss/camss-csiphy.c +++ b/drivers/media/platform/qcom/camss/camss-csiphy.c @@ -7,12 +7,14 @@ * Copyright (c) 2011-2015, The Linux Foundation. All rights reserved. * Copyright (C) 2016-2018 Linaro Ltd. */ +#include #include #include #include #include #include #include +#include #include #include #include @@ -131,10 +133,10 @@ static u8 csiphy_get_bpp(const struct csiphy_format_i= nfo *formats, } =20 /* - * csiphy_set_clock_rates - Calculate and set clock rates on CSIPHY module + * csiphy_set_clock_rates_legacy - Calculate and set clock rates on CSIPHY= module * @csiphy: CSIPHY device */ -static int csiphy_set_clock_rates(struct csiphy_device *csiphy) +static int csiphy_set_clock_rates_legacy(struct csiphy_device *csiphy) { struct device *dev =3D csiphy->camss->dev; s64 link_freq; @@ -200,7 +202,7 @@ static int csiphy_set_clock_rates(struct csiphy_device = *csiphy) * * Return 0 on success or a negative error code otherwise */ -static int csiphy_set_power(struct v4l2_subdev *sd, int on) +static int csiphy_set_power_legacy(struct v4l2_subdev *sd, int on) { struct csiphy_device *csiphy =3D v4l2_get_subdevdata(sd); struct device *dev =3D csiphy->camss->dev; @@ -219,7 +221,7 @@ static int csiphy_set_power(struct v4l2_subdev *sd, int= on) return ret; } =20 - ret =3D csiphy_set_clock_rates(csiphy); + ret =3D csiphy_set_clock_rates_legacy(csiphy); if (ret < 0) { regulator_bulk_disable(csiphy->num_supplies, csiphy->supplies); @@ -254,7 +256,7 @@ static int csiphy_set_power(struct v4l2_subdev *sd, int= on) } =20 /* - * csiphy_stream_on - Enable streaming on CSIPHY module + * csiphy_stream_on_legacy - Enable streaming on CSIPHY module * @csiphy: CSIPHY device * * Helper function to enable streaming on CSIPHY module. @@ -262,7 +264,7 @@ static int csiphy_set_power(struct v4l2_subdev *sd, int= on) * * Return 0 on success or a negative error code otherwise */ -static int csiphy_stream_on(struct csiphy_device *csiphy) +static int csiphy_stream_on_legacy(struct csiphy_device *csiphy) { struct csiphy_config *cfg =3D &csiphy->cfg; s64 link_freq; @@ -306,11 +308,86 @@ static int csiphy_stream_on(struct csiphy_device *csi= phy) * * Helper function to disable streaming on CSIPHY module */ -static void csiphy_stream_off(struct csiphy_device *csiphy) +static void csiphy_stream_off_legacy(struct csiphy_device *csiphy) { csiphy->res->hw_ops->lanes_disable(csiphy, &csiphy->cfg); } =20 +/* + * csiphy_stream_on - Enable streaming on CSIPHY module + * @csiphy: CSIPHY device + * + * Helper function to enable streaming on CSIPHY module. + * Main configuration of CSIPHY module is also done here. + * + * Return 0 on success or a negative error code otherwise + */ +static int csiphy_stream_on(struct csiphy_device *csiphy) +{ + u8 bpp =3D csiphy_get_bpp(csiphy->res->formats->formats, csiphy->res->for= mats->nformats, + csiphy->fmt[MSM_CSIPHY_PAD_SINK].code); + u8 num_lanes =3D csiphy->cfg.csi2->lane_cfg.num_data; + struct phy_configure_opts_mipi_dphy *dphy_cfg; + union phy_configure_opts dphy_opts =3D { 0 }; + struct device *dev =3D csiphy->camss->dev; + s64 link_freq; + int ret; + + dphy_cfg =3D &dphy_opts.mipi_dphy; + + link_freq =3D camss_get_link_freq(&csiphy->subdev.entity, bpp, num_lanes); + + if (link_freq < 0) { + dev_err(dev, + "Cannot get CSI2 transmitter's link frequency\n"); + return -EINVAL; + } + + phy_mipi_dphy_get_default_config_for_hsclk(link_freq, num_lanes, dphy_cfg= ); + + phy_set_mode(csiphy->phy, PHY_MODE_MIPI_DPHY); + ret =3D phy_configure(csiphy->phy, &dphy_opts); + if (ret) { + dev_err(dev, "failed to configure MIPI D-PHY\n"); + goto error; + } + + return phy_power_on(csiphy->phy); + +error: + return ret; +} + +/* + * csiphy_stream_off - Disable streaming on CSIPHY module + * @csiphy: CSIPHY device + * + * Helper function to disable streaming on CSIPHY module + */ +static void csiphy_stream_off(struct csiphy_device *csiphy) +{ + phy_power_off(csiphy->phy); +} + +/* + * csiphy_set_stream - Enable/disable streaming on CSIPHY module + * @sd: CSIPHY V4L2 subdevice + * @enable: Requested streaming state + * + * Return 0 on success or a negative error code otherwise + */ +static int csiphy_set_stream_legacy(struct v4l2_subdev *sd, int enable) +{ + struct csiphy_device *csiphy =3D v4l2_get_subdevdata(sd); + int ret =3D 0; + + if (enable) + ret =3D csiphy_stream_on_legacy(csiphy); + else + csiphy_stream_off_legacy(csiphy); + + return ret; +} =20 /* * csiphy_set_stream - Enable/disable streaming on CSIPHY module @@ -568,16 +645,16 @@ static bool csiphy_match_clock_name(const char *clock= _name, const char *format, } =20 /* - * msm_csiphy_subdev_init - Initialize CSIPHY device structure and resourc= es + * msm_csiphy_subdev_init_legacy - Initialize CSIPHY device structure and = resources * @csiphy: CSIPHY device * @res: CSIPHY module resources table * @id: CSIPHY module id * * Return 0 on success or a negative error code otherwise */ -int msm_csiphy_subdev_init(struct camss *camss, - struct csiphy_device *csiphy, - const struct camss_subdev_resources *res, u8 id) +int msm_csiphy_subdev_init_legacy(struct camss *camss, + struct csiphy_device *csiphy, + const struct camss_subdev_resources *res, u8 id) { struct device *dev =3D camss->dev; struct platform_device *pdev =3D to_platform_device(dev); @@ -705,6 +782,69 @@ int msm_csiphy_subdev_init(struct camss *camss, return ret; } =20 +/* + * msm_csiphy_subdev_init - Initialize CSIPHY device structure and resourc= es + * @csiphy: CSIPHY device + * @res: CSIPHY module resources table + * @id: CSIPHY module id + * + * Return 0 on success or a negative error code otherwise + */ +int msm_csiphy_subdev_init(struct camss *camss, + struct csiphy_device *csiphy, + const struct camss_subdev_resources *res, u8 id) +{ + struct device *dev =3D camss->dev; + struct of_phandle_args args; + u8 combo_mode; + int idx; + int ret; + + snprintf(csiphy->name, ARRAY_SIZE(csiphy->name), "csiphy%d", id); + + idx =3D of_property_match_string(dev->of_node, "phy-names", csiphy->name); + if (idx < 0) { + dev_err(dev, "%s not found\n", csiphy->name); + return idx; + } + + ret =3D of_parse_phandle_with_args(dev->of_node, "phys", "#phy-cells", id= x, &args); + if (ret < 0) { + dev_err(dev, "unable to parse phys args %s\n", csiphy->name); + return ret; + } + + if (!of_device_is_available(args.np)) + goto put_np; + + combo_mode =3D args.args[0]; + if (combo_mode !=3D PHY_TYPE_DPHY) { + dev_err(dev, "%s mode %d not supported\n", csiphy->name, combo_mode); + ret =3D -ENOTSUPP; + goto put_np; + } + + csiphy->phy =3D devm_phy_get(dev, csiphy->name); + if (IS_ERR(csiphy->phy)) { + ret =3D PTR_ERR(csiphy->phy); + goto put_np; + } + + csiphy->camss =3D camss; + csiphy->id =3D id; + csiphy->cfg.combo_mode =3D combo_mode; + csiphy->res =3D &res->csiphy; + + ret =3D phy_init(csiphy->phy); + if (ret) + dev_err(dev, "phy %s init fail %d\n", csiphy->name, ret); + +put_np: + of_node_put(args.np); + + return ret; +} + /* * csiphy_link_setup - Setup CSIPHY connections * @entity: Pointer to media entity structure @@ -739,8 +879,12 @@ static int csiphy_link_setup(struct media_entity *enti= ty, return 0; } =20 -static const struct v4l2_subdev_core_ops csiphy_core_ops =3D { - .s_power =3D csiphy_set_power, +static const struct v4l2_subdev_core_ops csiphy_core_ops_legacy =3D { + .s_power =3D csiphy_set_power_legacy, +}; + +static const struct v4l2_subdev_video_ops csiphy_video_ops_legacy =3D { + .s_stream =3D csiphy_set_stream_legacy, }; =20 static const struct v4l2_subdev_video_ops csiphy_video_ops =3D { @@ -754,8 +898,13 @@ static const struct v4l2_subdev_pad_ops csiphy_pad_ops= =3D { .set_fmt =3D csiphy_set_format, }; =20 +static const struct v4l2_subdev_ops csiphy_v4l2_ops_legacy =3D { + .core =3D &csiphy_core_ops_legacy, + .video =3D &csiphy_video_ops_legacy, + .pad =3D &csiphy_pad_ops, +}; + static const struct v4l2_subdev_ops csiphy_v4l2_ops =3D { - .core =3D &csiphy_core_ops, .video =3D &csiphy_video_ops, .pad =3D &csiphy_pad_ops, }; @@ -784,7 +933,11 @@ int msm_csiphy_register_entity(struct csiphy_device *c= siphy, struct device *dev =3D csiphy->camss->dev; int ret; =20 - v4l2_subdev_init(sd, &csiphy_v4l2_ops); + if (IS_ERR(csiphy->phy)) + v4l2_subdev_init(sd, &csiphy_v4l2_ops_legacy); + else + v4l2_subdev_init(sd, &csiphy_v4l2_ops); + sd->internal_ops =3D &csiphy_v4l2_internal_ops; sd->flags |=3D V4L2_SUBDEV_FL_HAS_DEVNODE; snprintf(sd->name, ARRAY_SIZE(sd->name), "%s%d", @@ -823,6 +976,8 @@ int msm_csiphy_register_entity(struct csiphy_device *cs= iphy, */ void msm_csiphy_unregister_entity(struct csiphy_device *csiphy) { + if (!IS_ERR(csiphy->phy)) + phy_exit(csiphy->phy); v4l2_device_unregister_subdev(&csiphy->subdev); media_entity_cleanup(&csiphy->subdev.entity); } diff --git a/drivers/media/platform/qcom/camss/camss-csiphy.h b/drivers/med= ia/platform/qcom/camss/camss-csiphy.h index 2d5054819df7f..25b803c06e8bf 100644 --- a/drivers/media/platform/qcom/camss/camss-csiphy.h +++ b/drivers/media/platform/qcom/camss/camss-csiphy.h @@ -12,6 +12,7 @@ =20 #include #include +#include #include #include #include @@ -95,6 +96,7 @@ struct csiphy_device_regs { =20 struct csiphy_device { struct camss *camss; + struct phy *phy; u8 id; struct v4l2_subdev subdev; struct media_pad pads[MSM_CSIPHY_PADS_NUM]; @@ -102,6 +104,7 @@ struct csiphy_device { void __iomem *base_clk_mux; u32 irq; char irq_name[30]; + char name[16]; struct camss_clock *clock; bool *rate_set; int nclocks; @@ -116,6 +119,10 @@ struct csiphy_device { =20 struct camss_subdev_resources; =20 +int msm_csiphy_subdev_init_legacy(struct camss *camss, + struct csiphy_device *csiphy, + const struct camss_subdev_resources *res, u8 id); + int msm_csiphy_subdev_init(struct camss *camss, struct csiphy_device *csiphy, const struct camss_subdev_resources *res, u8 id); diff --git a/drivers/media/platform/qcom/camss/camss.c b/drivers/media/plat= form/qcom/camss/camss.c index 5fb5ad87e1671..b1737b5d52160 100644 --- a/drivers/media/platform/qcom/camss/camss.c +++ b/drivers/media/platform/qcom/camss/camss.c @@ -4450,14 +4450,35 @@ static int camss_parse_endpoint_node(struct device = *dev, static int camss_parse_ports(struct camss *camss) { struct device *dev =3D camss->dev; + const struct camss_resources *res =3D camss->res; struct fwnode_handle *fwnode =3D dev_fwnode(dev), *ep; int ret; =20 fwnode_graph_for_each_endpoint(fwnode, ep) { struct camss_async_subdev *csd; + struct fwnode_handle *remote; + + if (!fwnode_device_is_available(ep)) + continue; + + if (res->legacy_phy) { + csd =3D v4l2_async_nf_add_fwnode_remote(&camss->notifier, ep, + typeof(*csd)); + } else { + /* + * For non-legacy PHY, the CSIPHY is a separate device. + * Register the remote endpoint (CSIPHY's endpoint) as + * the async subdev, not the remote port parent. + */ + remote =3D fwnode_graph_get_remote_endpoint(ep); + if (!remote) + continue; + + csd =3D v4l2_async_nf_add_fwnode(&camss->notifier, remote, + struct camss_async_subdev); + fwnode_handle_put(remote); + } =20 - csd =3D v4l2_async_nf_add_fwnode_remote(&camss->notifier, ep, - typeof(*csd)); if (IS_ERR(csd)) { ret =3D PTR_ERR(csd); goto err_cleanup; @@ -4489,15 +4510,26 @@ static int camss_init_subdevices(struct camss *cams= s) unsigned int i; int ret; =20 - for (i =3D 0; i < camss->res->csiphy_num; i++) { - ret =3D msm_csiphy_subdev_init(camss, &camss->csiphy[i], - &res->csiphy_res[i], - res->csiphy_res[i].csiphy.id); - if (ret < 0) { - dev_err(camss->dev, - "Failed to init csiphy%d sub-device: %d\n", - i, ret); - return ret; + if (!res->legacy_phy) { + for (i =3D 0; i < camss->res->csiphy_num; i++) { + ret =3D msm_csiphy_subdev_init(camss, &camss->csiphy[i], + &res->csiphy_res[i], + res->csiphy_res[i].csiphy.id); + if (ret < 0) + return ret; + } + } else { + for (i =3D 0; i < camss->res->csiphy_num; i++) { + ret =3D msm_csiphy_subdev_init_legacy(camss, &camss->csiphy[i], + &res->csiphy_res[i], + res->csiphy_res[i].csiphy.id); + if (ret < 0) { + dev_err(camss->dev, + "Failed to init csiphy%d sub-device: %d\n", + i, ret); + return ret; + } + camss->csiphy[i].phy =3D ERR_PTR(-ENODEV); } } =20 @@ -4574,6 +4606,9 @@ static int camss_link_entities(struct camss *camss) =20 for (i =3D 0; i < camss->res->csiphy_num; i++) { for (j =3D 0; j < camss->res->csid_num; j++) { + if (!camss->csiphy[i].phy) + continue; + ret =3D media_create_pad_link(&camss->csiphy[i].subdev.entity, MSM_CSIPHY_PAD_SRC, &camss->csid[j].subdev.entity, @@ -4683,6 +4718,9 @@ static int camss_register_entities(struct camss *cams= s) int ret; =20 for (i =3D 0; i < camss->res->csiphy_num; i++) { + if (!camss->csiphy[i].phy) + continue; + ret =3D msm_csiphy_register_entity(&camss->csiphy[i], &camss->v4l2_dev); if (ret < 0) { @@ -4738,8 +4776,10 @@ static int camss_register_entities(struct camss *cam= ss) =20 i =3D camss->res->csiphy_num; err_reg_csiphy: - for (i--; i >=3D 0; i--) - msm_csiphy_unregister_entity(&camss->csiphy[i]); + for (i--; i >=3D 0; i--) { + if (camss->csiphy[i].phy) + msm_csiphy_unregister_entity(&camss->csiphy[i]); + } =20 return ret; } @@ -4754,8 +4794,10 @@ static void camss_unregister_entities(struct camss *= camss) { unsigned int i; =20 - for (i =3D 0; i < camss->res->csiphy_num; i++) - msm_csiphy_unregister_entity(&camss->csiphy[i]); + for (i =3D 0; i < camss->res->csiphy_num; i++) { + if (camss->csiphy[i].phy) + msm_csiphy_unregister_entity(&camss->csiphy[i]); + } =20 for (i =3D 0; i < camss->res->csid_num; i++) msm_csid_unregister_entity(&camss->csid[i]); --=20 2.52.0