Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/1.1/patches/2220310/?format=api
{ "id": 2220310, "url": "http://patchwork.ozlabs.org/api/1.1/patches/2220310/?format=api", "web_url": "http://patchwork.ozlabs.org/project/linux-gpio/patch/20260406-gmsl2-3_serdes-v10-22-645560fedca5@analog.com/", "project": { "id": 42, "url": "http://patchwork.ozlabs.org/api/1.1/projects/42/?format=api", "name": "Linux GPIO development", "link_name": "linux-gpio", "list_id": "linux-gpio.vger.kernel.org", "list_email": "linux-gpio@vger.kernel.org", "web_url": "", "scm_url": "", "webscm_url": "" }, "msgid": "<20260406-gmsl2-3_serdes-v10-22-645560fedca5@analog.com>", "date": "2026-04-06T20:15:01", "name": "[v10,22/22] media: i2c: remove MAX96714 driver", "commit_ref": null, "pull_url": null, "state": "new", "archived": false, "hash": "70a3806f2cc96db021c65974d77c5596df16051f", "submitter": { "id": 88270, "url": "http://patchwork.ozlabs.org/api/1.1/people/88270/?format=api", "name": "Dumitru Ceclan via B4 Relay", "email": "devnull+dumitru.ceclan.analog.com@kernel.org" }, "delegate": null, "mbox": "http://patchwork.ozlabs.org/project/linux-gpio/patch/20260406-gmsl2-3_serdes-v10-22-645560fedca5@analog.com/mbox/", "series": [ { "id": 498894, "url": "http://patchwork.ozlabs.org/api/1.1/series/498894/?format=api", "web_url": "http://patchwork.ozlabs.org/project/linux-gpio/list/?series=498894", "date": "2026-04-06T20:14:42", "name": "media: i2c: add Maxim GMSL2/3 serializer and deserializer drivers", "version": 10, "mbox": "http://patchwork.ozlabs.org/series/498894/mbox/" } ], "comments": "http://patchwork.ozlabs.org/api/patches/2220310/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/2220310/checks/", "tags": {}, "headers": { "Return-Path": "\n <linux-gpio+bounces-34742-incoming=patchwork.ozlabs.org@vger.kernel.org>", "X-Original-To": [ "incoming@patchwork.ozlabs.org", "linux-gpio@vger.kernel.org" ], "Delivered-To": "patchwork-incoming@legolas.ozlabs.org", "Authentication-Results": [ "legolas.ozlabs.org;\n\tdkim=pass (2048-bit key;\n unprotected) header.d=kernel.org header.i=@kernel.org header.a=rsa-sha256\n header.s=k20201202 header.b=G25MeXBx;\n\tdkim-atps=neutral", "legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org\n (client-ip=2600:3c0a:e001:db::12fc:5321; helo=sea.lore.kernel.org;\n envelope-from=linux-gpio+bounces-34742-incoming=patchwork.ozlabs.org@vger.kernel.org;\n receiver=patchwork.ozlabs.org)", "smtp.subspace.kernel.org;\n\tdkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org\n header.b=\"G25MeXBx\"", "smtp.subspace.kernel.org;\n arc=none smtp.client-ip=10.30.226.201" ], "Received": [ "from sea.lore.kernel.org (sea.lore.kernel.org\n [IPv6:2600:3c0a:e001:db::12fc:5321])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4fqLNC3YYjz1yFt\n\tfor <incoming@patchwork.ozlabs.org>; Tue, 07 Apr 2026 06:22:19 +1000 (AEST)", "from smtp.subspace.kernel.org (conduit.subspace.kernel.org\n [100.90.174.1])\n\tby sea.lore.kernel.org (Postfix) with ESMTP id 7036A30F485C\n\tfor <incoming@patchwork.ozlabs.org>; Mon, 6 Apr 2026 20:16:22 +0000 (UTC)", "from localhost.localdomain (localhost.localdomain [127.0.0.1])\n\tby smtp.subspace.kernel.org (Postfix) with ESMTP id 5743E3A4F3F;\n\tMon, 6 Apr 2026 20:15:24 +0000 (UTC)", "from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org\n [10.30.226.201])\n\t(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))\n\t(No client certificate requested)\n\tby smtp.subspace.kernel.org (Postfix) with ESMTPS id 228FE3A16BC;\n\tMon, 6 Apr 2026 20:15:23 +0000 (UTC)", "by smtp.kernel.org (Postfix) with ESMTPS id 03A46C2BCB8;\n\tMon, 6 Apr 2026 20:15:23 +0000 (UTC)", "from aws-us-west-2-korg-lkml-1.web.codeaurora.org\n (localhost.localdomain [127.0.0.1])\n\tby smtp.lore.kernel.org (Postfix) with ESMTP id EFCC0FB5164;\n\tMon, 6 Apr 2026 20:15:22 +0000 (UTC)" ], "ARC-Seal": "i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116;\n\tt=1775506523; cv=none;\n b=T0CGEFhcR3ICQx/TFuhkoeg6Qkb15ec3XTUmhcTUaKjx9mjeLXevWH5+IMTkGi3MtSJZ7CvzFPUFlNRC2A6vqco8GN+eXUzm+oilmCI6mx3jsaz/JPvu91pQaRUqA3itwbT6N7tJoBLZhOHHShTfjqY+oNTl2iY1GUhTTkkrNZA=", "ARC-Message-Signature": "i=1; a=rsa-sha256; d=subspace.kernel.org;\n\ts=arc-20240116; t=1775506523; c=relaxed/simple;\n\tbh=EbdWOD/9CNgsIGOXxQZIdUYoNrH5oAupvfnz1lGy/jk=;\n\th=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References:\n\t In-Reply-To:To:Cc;\n b=Bp/+Qph4y6j9fWKTNMRiS4QU2/1FpUpSqhqyf8To6E/9aVWIC2kHvDpOokIGyvYxI6sZPY/tO2MIydBba9BoAb2tL83Xaa7JJym8uZI42rNDNUm3rZEyMqWM3e7nwuq+lIcx9hPD8m7krliHBDEGy2enhF/moNKs8np5uA6k2oc=", "ARC-Authentication-Results": "i=1; smtp.subspace.kernel.org;\n dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org\n header.b=G25MeXBx; arc=none smtp.client-ip=10.30.226.201", "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org;\n\ts=k20201202; t=1775506523;\n\tbh=EbdWOD/9CNgsIGOXxQZIdUYoNrH5oAupvfnz1lGy/jk=;\n\th=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From;\n\tb=G25MeXBxI32eJIC/MPFI4EY65vFqRwPPnV9HbxFjtuY9+irdKpkkfrug1vFSwH2LE\n\t PiucEnU4GWVwCgp/reyGF08e1M189CPINjJac6QuAMeCFYs6XdLa/TURpPHI/2yb59\n\t H6X5F+aKRKgB/H8xYBBjindpcQo21P5D3glOqLXV8l/fvVn9k6Wrq6nfSa442RdeaA\n\t FXJA7IHStqq8jXpPvifk2Gc61u44gbQXU1KfjiwrMv/tu+O9wCUJUPhI71Bp7KLnd0\n\t OY7F2gSmhIdhY6nIo3OtyDXO5PKNjnXCKaLrdfunQZE/J5Ps+lNwLaZX756McQuQAc\n\t KXhUd7epgIS0Q==", "From": "Dumitru Ceclan via B4 Relay\n <devnull+dumitru.ceclan.analog.com@kernel.org>", "Date": "Mon, 06 Apr 2026 23:15:01 +0300", "Subject": "[PATCH v10 22/22] media: i2c: remove MAX96714 driver", "Precedence": "bulk", "X-Mailing-List": "linux-gpio@vger.kernel.org", "List-Id": "<linux-gpio.vger.kernel.org>", "List-Subscribe": "<mailto:linux-gpio+subscribe@vger.kernel.org>", "List-Unsubscribe": "<mailto:linux-gpio+unsubscribe@vger.kernel.org>", "MIME-Version": "1.0", "Content-Type": "text/plain; charset=\"utf-8\"", "Content-Transfer-Encoding": "7bit", "Message-Id": "<20260406-gmsl2-3_serdes-v10-22-645560fedca5@analog.com>", "References": "<20260406-gmsl2-3_serdes-v10-0-645560fedca5@analog.com>", "In-Reply-To": "<20260406-gmsl2-3_serdes-v10-0-645560fedca5@analog.com>", "To": "Tomi Valkeinen <tomi.valkeinen+renesas@ideasonboard.com>,\n Mauro Carvalho Chehab <mchehab@kernel.org>,\n Sakari Ailus <sakari.ailus@linux.intel.com>,\n Laurent Pinchart <laurent.pinchart@ideasonboard.com>,\n Julien Massot <julien.massot@collabora.com>, Rob Herring <robh@kernel.org>,\n\t=?utf-8?q?Niklas_S=C3=B6derlund?= <niklas.soderlund@ragnatech.se>,\n Greg Kroah-Hartman <gregkh@linuxfoundation.org>,\n Cosmin Tanislav <cosmin.tanislav@analog.com>", "Cc": "mitrutzceclan@gmail.com, linux-media@vger.kernel.org,\n linux-kernel@vger.kernel.org, devicetree@vger.kernel.org,\n linux-staging@lists.linux.dev, linux-gpio@vger.kernel.org, =?utf-8?q?Nikla?=\n\t=?utf-8?q?s_S=C3=B6derlund?= <niklas.soderlund+renesas@ragnatech.se>,\n Martin Hecht <Martin.Hecht@avnet.eu>,\n Cosmin Tanislav <demonsingur@gmail.com>", "X-Mailer": "b4 0.14.3", "X-Developer-Signature": "v=1; a=ed25519-sha256; t=1775506518; l=31161;\n i=dumitru.ceclan@analog.com; s=20240313; h=from:subject:message-id;\n bh=WFCwbPIedig66ihSX7AbatVRFVu3MymAXOelV/k1f5I=;\n b=J9u4/D3kgkEc0WVP3BI8ddhO+uAbxOd4Ck1EOACL+lHAbsaONUI3pjTxxlSqEd+bRXj9jA6ux\n Pl9J4xTKV41CWmonmvv2Sp7jNrVTCEq9pECgk0BOg9L6NmsbGcCxPIF", "X-Developer-Key": "i=dumitru.ceclan@analog.com; a=ed25519;\n pk=HdqMlVyrcazwoiai7oN6ghU+Bj1pusGUFRl30jhS7Bo=", "X-Endpoint-Received": "by B4 Relay for dumitru.ceclan@analog.com/20240313\n with auth_id=140", "X-Original-From": "Dumitru Ceclan <dumitru.ceclan@analog.com>", "Reply-To": "dumitru.ceclan@analog.com" }, "content": "From: Cosmin Tanislav <demonsingur@gmail.com>\n\nRemove the MAX96714 driver. Its functionality has been moved to the\nMAX9296A driver which makes use of the Maxim GMSL2/3 serializer\nframework.\n\nSigned-off-by: Cosmin Tanislav <demonsingur@gmail.com>\nReviewed-by: Julien Massot <julien.massot@collabora.com>\n---\n MAINTAINERS | 1 -\n drivers/media/i2c/Kconfig | 17 -\n drivers/media/i2c/Makefile | 1 -\n drivers/media/i2c/max96714.c | 1017 ------------------------------------------\n 4 files changed, 1036 deletions(-)", "diff": "diff --git a/MAINTAINERS b/MAINTAINERS\nindex ad7e28897062..08ac1170baea 100644\n--- a/MAINTAINERS\n+++ b/MAINTAINERS\n@@ -15228,7 +15228,6 @@ M:\tJulien Massot <julien.massot@collabora.com>\n L:\tlinux-media@vger.kernel.org\n S:\tMaintained\n F:\tDocumentation/devicetree/bindings/media/i2c/maxim,max96714.yaml\n-F:\tdrivers/media/i2c/max96714.c\n \n MAX96717 GMSL2 SERIALIZER DRIVER\n M:\tJulien Massot <julien.massot@collabora.com>\ndiff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig\nindex 20a2261b64f9..669da3c63ad8 100644\n--- a/drivers/media/i2c/Kconfig\n+++ b/drivers/media/i2c/Kconfig\n@@ -1684,23 +1684,6 @@ config VIDEO_DS90UB960\n \t Device driver for the Texas Instruments DS90UB960\n \t FPD-Link III Deserializer and DS90UB9702 FPD-Link IV Deserializer.\n \n-config VIDEO_MAX96714\n-\ttristate \"Maxim MAX96714 GMSL2 deserializer\"\n-\tdepends on OF && I2C && VIDEO_DEV\n-\tselect I2C_MUX\n-\tselect MEDIA_CONTROLLER\n-\tselect GPIOLIB\n-\tselect V4L2_CCI_I2C\n-\tselect V4L2_FWNODE\n-\tselect VIDEO_V4L2_SUBDEV_API\n-\thelp\n-\t Device driver for the Maxim MAX96714 GMSL2 Deserializer.\n-\t MAX96714 deserializers convert a GMSL2 input to MIPI CSI-2\n-\t output.\n-\n-\t To compile this driver as a module, choose M here: the\n-\t module will be called max96714.\n-\n source \"drivers/media/i2c/maxim-serdes/Kconfig\"\n \n endmenu\ndiff --git a/drivers/media/i2c/Makefile b/drivers/media/i2c/Makefile\nindex 96bc49339341..333e4243ea2f 100644\n--- a/drivers/media/i2c/Makefile\n+++ b/drivers/media/i2c/Makefile\n@@ -69,7 +69,6 @@ obj-$(CONFIG_VIDEO_LT6911UXE) += lt6911uxe.o\n obj-$(CONFIG_VIDEO_M52790) += m52790.o\n obj-$(CONFIG_VIDEO_MAX9271_LIB) += max9271.o\n obj-$(CONFIG_VIDEO_MAX9286) += max9286.o\n-obj-$(CONFIG_VIDEO_MAX96714) += max96714.o\n obj-$(CONFIG_VIDEO_MAXIM_SERDES) += maxim-serdes/\n obj-$(CONFIG_VIDEO_ML86V7667) += ml86v7667.o\n obj-$(CONFIG_VIDEO_MSP3400) += msp3400.o\ndiff --git a/drivers/media/i2c/max96714.c b/drivers/media/i2c/max96714.c\ndeleted file mode 100644\nindex e3e625e6f11a..000000000000\n--- a/drivers/media/i2c/max96714.c\n+++ /dev/null\n@@ -1,1017 +0,0 @@\n-// SPDX-License-Identifier: GPL-2.0\n-/*\n- * Maxim GMSL2 Deserializer Driver\n- *\n- * Copyright (C) 2024 Collabora Ltd.\n- */\n-\n-#include <linux/bitfield.h>\n-#include <linux/bitops.h>\n-#include <linux/gpio/consumer.h>\n-#include <linux/i2c.h>\n-#include <linux/i2c-mux.h>\n-#include <linux/module.h>\n-#include <linux/property.h>\n-#include <linux/regmap.h>\n-#include <linux/regulator/consumer.h>\n-\n-#include <media/v4l2-cci.h>\n-#include <media/v4l2-ctrls.h>\n-#include <media/v4l2-fwnode.h>\n-#include <media/v4l2-subdev.h>\n-\n-#define MAX96714_DEVICE_ID 0xc9\n-#define MAX96714F_DEVICE_ID 0xca\n-#define MAX96714_NPORTS 2\n-#define MAX96714_PAD_SINK 0\n-#define MAX96714_PAD_SOURCE 1\n-#define MAX96714_CSI_NLANES 4\n-\n-/* DEV */\n-#define MAX96714_REG13 CCI_REG8(0x0d)\n-#define MAX96714_DEV_REV CCI_REG8(0x0e)\n-#define MAX96714_DEV_REV_MASK GENMASK(3, 0)\n-#define MAX96714_LINK_LOCK CCI_REG8(0x13)\n-#define MAX96714_LINK_LOCK_BIT BIT(3)\n-#define MAX96714_IO_CHK0 CCI_REG8(0x38)\n-#define MAX96714_PATTERN_CLK_FREQ GENMASK(1, 0)\n-/* VID_RX */\n-#define MAX96714_VIDEO_RX8 CCI_REG8(0x11a)\n-#define MAX96714_VID_LOCK BIT(6)\n-\n-/* VRX_PATGEN_0 */\n-#define MAX96714_PATGEN_0 CCI_REG8(0x240)\n-#define MAX96714_PATGEN_1 CCI_REG8(0x241)\n-#define MAX96714_PATGEN_MODE GENMASK(5, 4)\n-#define MAX96714_PATGEN_VS_DLY CCI_REG24(0x242)\n-#define MAX96714_PATGEN_VS_HIGH CCI_REG24(0x245)\n-#define MAX96714_PATGEN_VS_LOW CCI_REG24(0x248)\n-#define MAX96714_PATGEN_V2H CCI_REG24(0x24b)\n-#define MAX96714_PATGEN_HS_HIGH CCI_REG16(0x24e)\n-#define MAX96714_PATGEN_HS_LOW CCI_REG16(0x250)\n-#define MAX96714_PATGEN_HS_CNT CCI_REG16(0x252)\n-#define MAX96714_PATGEN_V2D CCI_REG24(0x254)\n-#define MAX96714_PATGEN_DE_HIGH CCI_REG16(0x257)\n-#define MAX96714_PATGEN_DE_LOW CCI_REG16(0x259)\n-#define MAX96714_PATGEN_DE_CNT CCI_REG16(0x25b)\n-#define MAX96714_PATGEN_GRAD_INC CCI_REG8(0x25d)\n-#define MAX96714_PATGEN_CHKB_COLOR_A CCI_REG24(0x25e)\n-#define MAX96714_PATGEN_CHKB_COLOR_B CCI_REG24(0x261)\n-#define MAX96714_PATGEN_CHKB_RPT_CNT_A CCI_REG8(0x264)\n-#define MAX96714_PATGEN_CHKB_RPT_CNT_B CCI_REG8(0x265)\n-#define MAX96714_PATGEN_CHKB_ALT CCI_REG8(0x266)\n-/* BACKTOP */\n-#define MAX96714_BACKTOP25 CCI_REG8(0x320)\n-#define CSI_DPLL_FREQ_MASK GENMASK(4, 0)\n-\n-/* MIPI_PHY */\n-#define MAX96714_MIPI_PHY0 CCI_REG8(0x330)\n-#define MAX96714_FORCE_CSI_OUT BIT(7)\n-#define MAX96714_MIPI_STDBY_N CCI_REG8(0x332)\n-#define MAX96714_MIPI_STDBY_MASK GENMASK(5, 4)\n-#define MAX96714_MIPI_LANE_MAP CCI_REG8(0x333)\n-#define MAX96714_MIPI_POLARITY CCI_REG8(0x335)\n-#define MAX96714_MIPI_POLARITY_MASK GENMASK(5, 0)\n-\n-/* MIPI_TX */\n-#define MAX96714_MIPI_LANE_CNT CCI_REG8(0x44a)\n-#define MAX96714_CSI2_LANE_CNT_MASK GENMASK(7, 6)\n-#define MAX96714_MIPI_TX52 CCI_REG8(0x474)\n-#define MAX96714_TUN_EN BIT(0)\n-\n-#define MHZ(v) ((u32)((v) * 1000000U))\n-\n-enum max96714_vpg_mode {\n-\tMAX96714_VPG_DISABLED = 0,\n-\tMAX96714_VPG_CHECKERBOARD = 1,\n-\tMAX96714_VPG_GRADIENT = 2,\n-};\n-\n-struct max96714_rxport {\n-\tstruct {\n-\t\tstruct v4l2_subdev *sd;\n-\t\tu16 pad;\n-\t\tstruct fwnode_handle *ep_fwnode;\n-\t} source;\n-\tstruct regulator\t *poc;\n-};\n-\n-struct max96714_txport {\n-\tstruct v4l2_fwnode_endpoint vep;\n-};\n-\n-struct max96714_priv {\n-\tstruct i2c_client *client;\n-\tstruct regmap *regmap;\n-\tstruct gpio_desc *pd_gpio;\n-\tstruct max96714_rxport rxport;\n-\tstruct i2c_mux_core *mux;\n-\tu64 enabled_source_streams;\n-\tstruct v4l2_subdev\t\t sd;\n-\tstruct media_pad\t\t pads[MAX96714_NPORTS];\n-\tstruct v4l2_mbus_config_mipi_csi2 mipi_csi2;\n-\tstruct v4l2_ctrl_handler ctrl_handler;\n-\tstruct v4l2_async_notifier notifier;\n-\ts64 tx_link_freq;\n-\tenum max96714_vpg_mode pattern;\n-};\n-\n-static inline struct max96714_priv *sd_to_max96714(struct v4l2_subdev *sd)\n-{\n-\treturn container_of(sd, struct max96714_priv, sd);\n-}\n-\n-static int max96714_enable_tx_port(struct max96714_priv *priv)\n-{\n-\treturn cci_update_bits(priv->regmap, MAX96714_MIPI_STDBY_N,\n-\t\t\t MAX96714_MIPI_STDBY_MASK,\n-\t\t\t MAX96714_MIPI_STDBY_MASK, NULL);\n-}\n-\n-static int max96714_disable_tx_port(struct max96714_priv *priv)\n-{\n-\treturn cci_update_bits(priv->regmap, MAX96714_MIPI_STDBY_N,\n-\t\t\t MAX96714_MIPI_STDBY_MASK, 0, NULL);\n-}\n-\n-static bool max96714_tx_port_enabled(struct max96714_priv *priv)\n-{\n-\tu64 val;\n-\n-\tcci_read(priv->regmap, MAX96714_MIPI_STDBY_N, &val, NULL);\n-\n-\treturn val & MAX96714_MIPI_STDBY_MASK;\n-}\n-\n-static int max96714_apply_patgen_timing(struct max96714_priv *priv,\n-\t\t\t\t\tstruct v4l2_subdev_state *state)\n-{\n-\tstruct v4l2_mbus_framefmt *fmt =\n-\t\tv4l2_subdev_state_get_format(state, MAX96714_PAD_SOURCE);\n-\tconst u32 h_active = fmt->width;\n-\tconst u32 h_fp = 88;\n-\tconst u32 h_sw = 44;\n-\tconst u32 h_bp = 148;\n-\tu32 h_tot;\n-\tconst u32 v_active = fmt->height;\n-\tconst u32 v_fp = 4;\n-\tconst u32 v_sw = 5;\n-\tconst u32 v_bp = 36;\n-\tu32 v_tot;\n-\tint ret = 0;\n-\n-\th_tot = h_active + h_fp + h_sw + h_bp;\n-\tv_tot = v_active + v_fp + v_sw + v_bp;\n-\n-\t/* 75 Mhz pixel clock */\n-\tcci_update_bits(priv->regmap, MAX96714_IO_CHK0,\n-\t\t\tMAX96714_PATTERN_CLK_FREQ, 1, &ret);\n-\n-\tdev_info(&priv->client->dev, \"height: %d width: %d\\n\", fmt->height,\n-\t\t fmt->width);\n-\n-\tcci_write(priv->regmap, MAX96714_PATGEN_VS_DLY, 0, &ret);\n-\tcci_write(priv->regmap, MAX96714_PATGEN_VS_HIGH, v_sw * h_tot, &ret);\n-\tcci_write(priv->regmap, MAX96714_PATGEN_VS_LOW,\n-\t\t (v_active + v_fp + v_bp) * h_tot, &ret);\n-\tcci_write(priv->regmap, MAX96714_PATGEN_HS_HIGH, h_sw, &ret);\n-\tcci_write(priv->regmap, MAX96714_PATGEN_HS_LOW, h_active + h_fp + h_bp,\n-\t\t &ret);\n-\tcci_write(priv->regmap, MAX96714_PATGEN_V2D,\n-\t\t h_tot * (v_sw + v_bp) + (h_sw + h_bp), &ret);\n-\tcci_write(priv->regmap, MAX96714_PATGEN_HS_CNT, v_tot, &ret);\n-\tcci_write(priv->regmap, MAX96714_PATGEN_DE_HIGH, h_active, &ret);\n-\tcci_write(priv->regmap, MAX96714_PATGEN_DE_LOW, h_fp + h_sw + h_bp,\n-\t\t &ret);\n-\tcci_write(priv->regmap, MAX96714_PATGEN_DE_CNT, v_active, &ret);\n-\t/* B G R */\n-\tcci_write(priv->regmap, MAX96714_PATGEN_CHKB_COLOR_A, 0xfecc00, &ret);\n-\t/* B G R */\n-\tcci_write(priv->regmap, MAX96714_PATGEN_CHKB_COLOR_B, 0x006aa7, &ret);\n-\tcci_write(priv->regmap, MAX96714_PATGEN_CHKB_RPT_CNT_A, 0x3c, &ret);\n-\tcci_write(priv->regmap, MAX96714_PATGEN_CHKB_RPT_CNT_B, 0x3c, &ret);\n-\tcci_write(priv->regmap, MAX96714_PATGEN_CHKB_ALT, 0x3c, &ret);\n-\tcci_write(priv->regmap, MAX96714_PATGEN_GRAD_INC, 0x10, &ret);\n-\n-\treturn ret;\n-}\n-\n-static int max96714_apply_patgen(struct max96714_priv *priv,\n-\t\t\t\t struct v4l2_subdev_state *state)\n-{\n-\tunsigned int val;\n-\tint ret = 0;\n-\n-\tif (priv->pattern)\n-\t\tret = max96714_apply_patgen_timing(priv, state);\n-\n-\tcci_write(priv->regmap, MAX96714_PATGEN_0, priv->pattern ? 0xfb : 0,\n-\t\t &ret);\n-\n-\tval = FIELD_PREP(MAX96714_PATGEN_MODE, priv->pattern);\n-\tcci_update_bits(priv->regmap, MAX96714_PATGEN_1, MAX96714_PATGEN_MODE,\n-\t\t\tval, &ret);\n-\treturn ret;\n-}\n-\n-static int max96714_s_ctrl(struct v4l2_ctrl *ctrl)\n-{\n-\tstruct max96714_priv *priv =\n-\t\tcontainer_of(ctrl->handler, struct max96714_priv, ctrl_handler);\n-\tint ret;\n-\n-\tswitch (ctrl->id) {\n-\tcase V4L2_CID_TEST_PATTERN:\n-\t\tif (priv->enabled_source_streams)\n-\t\t\treturn -EBUSY;\n-\t\tpriv->pattern = ctrl->val;\n-\t\tbreak;\n-\tdefault:\n-\t\treturn -EINVAL;\n-\t}\n-\n-\tret = cci_update_bits(priv->regmap, MAX96714_MIPI_PHY0,\n-\t\t\t MAX96714_FORCE_CSI_OUT,\n-\t\t\t priv->pattern ? MAX96714_FORCE_CSI_OUT : 0, NULL);\n-\n-\t/* Pattern generator doesn't work with tunnel mode */\n-\treturn cci_update_bits(priv->regmap, MAX96714_MIPI_TX52,\n-\t\t\t MAX96714_TUN_EN,\n-\t\t\t priv->pattern ? 0 : MAX96714_TUN_EN, &ret);\n-}\n-\n-static const char * const max96714_test_pattern[] = {\n-\t\"Disabled\",\n-\t\"Checkerboard\",\n-\t\"Gradient\"\n-};\n-\n-static const struct v4l2_ctrl_ops max96714_ctrl_ops = {\n-\t.s_ctrl = max96714_s_ctrl,\n-};\n-\n-static int max96714_enable_streams(struct v4l2_subdev *sd,\n-\t\t\t\t struct v4l2_subdev_state *state,\n-\t\t\t\t u32 source_pad, u64 streams_mask)\n-{\n-\tstruct max96714_priv *priv = sd_to_max96714(sd);\n-\tu64 sink_streams;\n-\tint ret;\n-\n-\tif (!priv->enabled_source_streams)\n-\t\tmax96714_enable_tx_port(priv);\n-\n-\tret = max96714_apply_patgen(priv, state);\n-\tif (ret)\n-\t\tgoto err;\n-\n-\tif (!priv->pattern) {\n-\t\tif (!priv->rxport.source.sd) {\n-\t\t\tret = -ENODEV;\n-\t\t\tgoto err;\n-\t\t}\n-\n-\t\tsink_streams =\n-\t\t\tv4l2_subdev_state_xlate_streams(state,\n-\t\t\t\t\t\t\tMAX96714_PAD_SOURCE,\n-\t\t\t\t\t\t\tMAX96714_PAD_SINK,\n-\t\t\t\t\t\t\t&streams_mask);\n-\n-\t\tret = v4l2_subdev_enable_streams(priv->rxport.source.sd,\n-\t\t\t\t\t\t priv->rxport.source.pad,\n-\t\t\t\t\t\t sink_streams);\n-\t\tif (ret)\n-\t\t\tgoto err;\n-\t}\n-\n-\tpriv->enabled_source_streams |= streams_mask;\n-\n-\treturn 0;\n-\n-err:\n-\tif (!priv->enabled_source_streams)\n-\t\tmax96714_disable_tx_port(priv);\n-\n-\treturn ret;\n-}\n-\n-static int max96714_disable_streams(struct v4l2_subdev *sd,\n-\t\t\t\t struct v4l2_subdev_state *state,\n-\t\t\t\t u32 source_pad, u64 streams_mask)\n-{\n-\tstruct max96714_priv *priv = sd_to_max96714(sd);\n-\tu64 sink_streams;\n-\n-\tif (!priv->pattern) {\n-\t\tint ret;\n-\n-\t\tsink_streams =\n-\t\t\tv4l2_subdev_state_xlate_streams(state,\n-\t\t\t\t\t\t\tMAX96714_PAD_SOURCE,\n-\t\t\t\t\t\t\tMAX96714_PAD_SINK,\n-\t\t\t\t\t\t\t&streams_mask);\n-\n-\t\tret = v4l2_subdev_disable_streams(priv->rxport.source.sd,\n-\t\t\t\t\t\t priv->rxport.source.pad,\n-\t\t\t\t\t\t sink_streams);\n-\t\tif (ret)\n-\t\t\treturn ret;\n-\t}\n-\n-\tpriv->enabled_source_streams &= ~streams_mask;\n-\n-\tif (!priv->enabled_source_streams)\n-\t\tmax96714_disable_tx_port(priv);\n-\n-\treturn 0;\n-}\n-\n-static int max96714_set_fmt(struct v4l2_subdev *sd,\n-\t\t\t struct v4l2_subdev_state *state,\n-\t\t\t struct v4l2_subdev_format *format)\n-{\n-\tstruct max96714_priv *priv = sd_to_max96714(sd);\n-\tstruct v4l2_mbus_framefmt *fmt;\n-\n-\tif (format->which == V4L2_SUBDEV_FORMAT_ACTIVE &&\n-\t priv->enabled_source_streams)\n-\t\treturn -EBUSY;\n-\n-\t/* No transcoding, source and sink formats must match. */\n-\tif (format->pad == MAX96714_PAD_SOURCE)\n-\t\treturn v4l2_subdev_get_fmt(sd, state, format);\n-\n-\tfmt = v4l2_subdev_state_get_format(state, format->pad, format->stream);\n-\tif (!fmt)\n-\t\treturn -EINVAL;\n-\n-\t*fmt = format->format;\n-\n-\tfmt = v4l2_subdev_state_get_opposite_stream_format(state, format->pad,\n-\t\t\t\t\t\t\t format->stream);\n-\tif (!fmt)\n-\t\treturn -EINVAL;\n-\n-\t*fmt = format->format;\n-\n-\treturn 0;\n-}\n-\n-static int _max96714_set_routing(struct v4l2_subdev *sd,\n-\t\t\t\t struct v4l2_subdev_state *state,\n-\t\t\t\t enum v4l2_subdev_format_whence which,\n-\t\t\t\t struct v4l2_subdev_krouting *routing)\n-{\n-\tstatic const struct v4l2_mbus_framefmt format = {\n-\t\t.width = 1280,\n-\t\t.height = 1080,\n-\t\t.code = MEDIA_BUS_FMT_Y8_1X8,\n-\t\t.field = V4L2_FIELD_NONE,\n-\t};\n-\tint ret;\n-\n-\tret = v4l2_subdev_routing_validate(sd, routing,\n-\t\t\t\t\t V4L2_SUBDEV_ROUTING_ONLY_1_TO_1);\n-\tif (ret)\n-\t\treturn ret;\n-\n-\treturn v4l2_subdev_set_routing_with_fmt(sd, state, routing, &format);\n-}\n-\n-static int max96714_set_routing(struct v4l2_subdev *sd,\n-\t\t\t\tstruct v4l2_subdev_state *state,\n-\t\t\t\tenum v4l2_subdev_format_whence which,\n-\t\t\t\tstruct v4l2_subdev_krouting *routing)\n-{\n-\tstruct max96714_priv *priv = sd_to_max96714(sd);\n-\n-\tif (which == V4L2_SUBDEV_FORMAT_ACTIVE && priv->enabled_source_streams)\n-\t\treturn -EBUSY;\n-\n-\treturn _max96714_set_routing(sd, state, which, routing);\n-}\n-\n-static int max96714_init_state(struct v4l2_subdev *sd,\n-\t\t\t struct v4l2_subdev_state *state)\n-{\n-\tstruct v4l2_subdev_route routes[] = {\n-\t\t{\n-\t\t\t.sink_pad = MAX96714_PAD_SINK,\n-\t\t\t.sink_stream = 0,\n-\t\t\t.source_pad = MAX96714_PAD_SOURCE,\n-\t\t\t.source_stream = 0,\n-\t\t\t.flags = V4L2_SUBDEV_ROUTE_FL_ACTIVE,\n-\t\t}\n-\t};\n-\tstruct v4l2_subdev_krouting routing = {\n-\t\t.num_routes = ARRAY_SIZE(routes),\n-\t\t.routes = routes,\n-\t};\n-\n-\treturn _max96714_set_routing(sd, state, V4L2_SUBDEV_FORMAT_ACTIVE,\n-\t\t\t\t &routing);\n-}\n-\n-static const struct v4l2_subdev_pad_ops max96714_pad_ops = {\n-\t.enable_streams = max96714_enable_streams,\n-\t.disable_streams = max96714_disable_streams,\n-\n-\t.set_routing = max96714_set_routing,\n-\t.get_fmt = v4l2_subdev_get_fmt,\n-\t.set_fmt = max96714_set_fmt,\n-};\n-\n-static bool max96714_link_locked(struct max96714_priv *priv)\n-{\n-\tu64 val = 0;\n-\n-\tcci_read(priv->regmap, MAX96714_LINK_LOCK, &val, NULL);\n-\n-\treturn val & MAX96714_LINK_LOCK_BIT;\n-}\n-\n-static void max96714_link_status(struct max96714_priv *priv)\n-{\n-\tstruct device *dev = &priv->client->dev;\n-\n-\tdev_info(dev, \"Link locked:%d\\n\", max96714_link_locked(priv));\n-}\n-\n-static bool max96714_pipe_locked(struct max96714_priv *priv)\n-{\n-\tu64 val;\n-\n-\tcci_read(priv->regmap, MAX96714_VIDEO_RX8, &val, NULL);\n-\n-\treturn val & MAX96714_VID_LOCK;\n-}\n-\n-static void max96714_pipe_status(struct max96714_priv *priv)\n-{\n-\tstruct device *dev = &priv->client->dev;\n-\n-\tdev_info(dev, \"Pipe vidlock:%d\\n\", max96714_pipe_locked(priv));\n-}\n-\n-static void max96714_csi_status(struct max96714_priv *priv)\n-{\n-\tstruct device *dev = &priv->client->dev;\n-\tu64 freq = 0;\n-\n-\tcci_read(priv->regmap, MAX96714_BACKTOP25, &freq, NULL);\n-\tfreq = FIELD_GET(CSI_DPLL_FREQ_MASK, freq);\n-\n-\tdev_info(dev, \"CSI controller DPLL freq:%u00MHz CSIPHY enabled:%d\\n\",\n-\t\t (u8)freq, max96714_tx_port_enabled(priv));\n-}\n-\n-static int max96714_log_status(struct v4l2_subdev *sd)\n-{\n-\tstruct max96714_priv *priv = sd_to_max96714(sd);\n-\tstruct device *dev = &priv->client->dev;\n-\n-\tdev_info(dev, \"Deserializer: max96714\\n\");\n-\n-\tmax96714_link_status(priv);\n-\tmax96714_pipe_status(priv);\n-\tmax96714_csi_status(priv);\n-\n-\treturn 0;\n-}\n-\n-static const struct v4l2_subdev_core_ops max96714_subdev_core_ops = {\n-\t.log_status = max96714_log_status,\n-};\n-\n-static const struct v4l2_subdev_video_ops max96714_video_ops = {\n-\t.s_stream\t= v4l2_subdev_s_stream_helper,\n-};\n-\n-static const struct v4l2_subdev_internal_ops max96714_internal_ops = {\n-\t.init_state = max96714_init_state,\n-};\n-\n-static const struct v4l2_subdev_ops max96714_subdev_ops = {\n-\t.video = &max96714_video_ops,\n-\t.core = &max96714_subdev_core_ops,\n-\t.pad = &max96714_pad_ops,\n-};\n-\n-static const struct media_entity_operations max96714_entity_ops = {\n-\t.link_validate = v4l2_subdev_link_validate,\n-};\n-\n-static int max96714_notify_bound(struct v4l2_async_notifier *notifier,\n-\t\t\t\t struct v4l2_subdev *subdev,\n-\t\t\t\t struct v4l2_async_connection *asd)\n-{\n-\tstruct max96714_priv *priv = sd_to_max96714(notifier->sd);\n-\tstruct device *dev = &priv->client->dev;\n-\tint ret;\n-\n-\tret = media_entity_get_fwnode_pad(&subdev->entity,\n-\t\t\t\t\t priv->rxport.source.ep_fwnode,\n-\t\t\t\t\t MEDIA_PAD_FL_SOURCE);\n-\tif (ret < 0) {\n-\t\tdev_err(dev, \"Failed to find pad for %s\\n\", subdev->name);\n-\t\treturn ret;\n-\t}\n-\n-\tpriv->rxport.source.sd = subdev;\n-\tpriv->rxport.source.pad = ret;\n-\n-\tret = media_create_pad_link(&priv->rxport.source.sd->entity,\n-\t\t\t\t priv->rxport.source.pad, &priv->sd.entity,\n-\t\t\t\t MAX96714_PAD_SINK,\n-\t\t\t\t MEDIA_LNK_FL_ENABLED |\n-\t\t\t\t MEDIA_LNK_FL_IMMUTABLE);\n-\tif (ret) {\n-\t\tdev_err(dev, \"Unable to link %s:%u -> %s:%u\\n\",\n-\t\t\tpriv->rxport.source.sd->name, priv->rxport.source.pad,\n-\t\t\tpriv->sd.name, MAX96714_PAD_SINK);\n-\t\treturn ret;\n-\t}\n-\n-\treturn 0;\n-}\n-\n-static const struct v4l2_async_notifier_operations max96714_notify_ops = {\n-\t.bound = max96714_notify_bound,\n-};\n-\n-static int max96714_v4l2_notifier_register(struct max96714_priv *priv)\n-{\n-\tstruct device *dev = &priv->client->dev;\n-\tstruct max96714_rxport *rxport = &priv->rxport;\n-\tstruct v4l2_async_connection *asd;\n-\tint ret;\n-\n-\tif (!rxport->source.ep_fwnode)\n-\t\treturn 0;\n-\n-\tv4l2_async_subdev_nf_init(&priv->notifier, &priv->sd);\n-\n-\tasd = v4l2_async_nf_add_fwnode(&priv->notifier,\n-\t\t\t\t rxport->source.ep_fwnode,\n-\t\t\t\t struct v4l2_async_connection);\n-\tif (IS_ERR(asd)) {\n-\t\tdev_err(dev, \"Failed to add subdev: %pe\", asd);\n-\t\tv4l2_async_nf_cleanup(&priv->notifier);\n-\t\treturn PTR_ERR(asd);\n-\t}\n-\n-\tpriv->notifier.ops = &max96714_notify_ops;\n-\n-\tret = v4l2_async_nf_register(&priv->notifier);\n-\tif (ret) {\n-\t\tdev_err(dev, \"Failed to register subdev_notifier\");\n-\t\tv4l2_async_nf_cleanup(&priv->notifier);\n-\t\treturn ret;\n-\t}\n-\n-\treturn 0;\n-}\n-\n-static int max96714_create_subdev(struct max96714_priv *priv)\n-{\n-\tstruct device *dev = &priv->client->dev;\n-\tint ret;\n-\n-\tv4l2_i2c_subdev_init(&priv->sd, priv->client, &max96714_subdev_ops);\n-\tpriv->sd.internal_ops = &max96714_internal_ops;\n-\n-\tv4l2_ctrl_handler_init(&priv->ctrl_handler, 1);\n-\tpriv->sd.ctrl_handler = &priv->ctrl_handler;\n-\n-\tv4l2_ctrl_new_int_menu(&priv->ctrl_handler, NULL, V4L2_CID_LINK_FREQ,\n-\t\t\t 0, 0, &priv->tx_link_freq);\n-\tv4l2_ctrl_new_std_menu_items(&priv->ctrl_handler,\n-\t\t\t\t &max96714_ctrl_ops,\n-\t\t\t\t V4L2_CID_TEST_PATTERN,\n-\t\t\t\t ARRAY_SIZE(max96714_test_pattern) - 1,\n-\t\t\t\t 0, 0, max96714_test_pattern);\n-\tif (priv->ctrl_handler.error) {\n-\t\tret = priv->ctrl_handler.error;\n-\t\tgoto err_free_ctrl;\n-\t}\n-\n-\tpriv->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_STREAMS;\n-\tpriv->sd.entity.function = MEDIA_ENT_F_VID_IF_BRIDGE;\n-\tpriv->sd.entity.ops = &max96714_entity_ops;\n-\n-\tpriv->pads[MAX96714_PAD_SINK].flags = MEDIA_PAD_FL_SINK;\n-\tpriv->pads[MAX96714_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;\n-\n-\tret = media_entity_pads_init(&priv->sd.entity,\n-\t\t\t\t MAX96714_NPORTS,\n-\t\t\t\t priv->pads);\n-\tif (ret)\n-\t\tgoto err_free_ctrl;\n-\n-\tpriv->sd.state_lock = priv->sd.ctrl_handler->lock;\n-\n-\tret = v4l2_subdev_init_finalize(&priv->sd);\n-\tif (ret)\n-\t\tgoto err_entity_cleanup;\n-\n-\tret = max96714_v4l2_notifier_register(priv);\n-\tif (ret) {\n-\t\tdev_err(dev, \"v4l2 subdev notifier register failed: %d\\n\", ret);\n-\t\tgoto err_subdev_cleanup;\n-\t}\n-\n-\tret = v4l2_async_register_subdev(&priv->sd);\n-\tif (ret) {\n-\t\tdev_err(dev, \"v4l2_async_register_subdev error: %d\\n\", ret);\n-\t\tgoto err_unreg_notif;\n-\t}\n-\n-\treturn 0;\n-\n-err_unreg_notif:\n-\tv4l2_async_nf_unregister(&priv->notifier);\n-\tv4l2_async_nf_cleanup(&priv->notifier);\n-err_subdev_cleanup:\n-\tv4l2_subdev_cleanup(&priv->sd);\n-err_entity_cleanup:\n-\tmedia_entity_cleanup(&priv->sd.entity);\n-err_free_ctrl:\n-\tv4l2_ctrl_handler_free(&priv->ctrl_handler);\n-\n-\treturn ret;\n-};\n-\n-static void max96714_destroy_subdev(struct max96714_priv *priv)\n-{\n-\tv4l2_async_nf_unregister(&priv->notifier);\n-\tv4l2_async_nf_cleanup(&priv->notifier);\n-\tv4l2_async_unregister_subdev(&priv->sd);\n-\n-\tv4l2_subdev_cleanup(&priv->sd);\n-\n-\tmedia_entity_cleanup(&priv->sd.entity);\n-\tv4l2_ctrl_handler_free(&priv->ctrl_handler);\n-}\n-\n-static int max96714_i2c_mux_select(struct i2c_mux_core *mux, u32 chan)\n-{\n-\treturn 0;\n-}\n-\n-static int max96714_i2c_mux_init(struct max96714_priv *priv)\n-{\n-\tpriv->mux = i2c_mux_alloc(priv->client->adapter, &priv->client->dev,\n-\t\t\t\t 1, 0, I2C_MUX_LOCKED | I2C_MUX_GATE,\n-\t\t\t\t max96714_i2c_mux_select, NULL);\n-\tif (!priv->mux)\n-\t\treturn -ENOMEM;\n-\n-\treturn i2c_mux_add_adapter(priv->mux, 0, 0);\n-}\n-\n-static int max96714_init_tx_port(struct max96714_priv *priv)\n-{\n-\tstruct v4l2_mbus_config_mipi_csi2 *mipi;\n-\tunsigned long lanes_used = 0;\n-\tunsigned int val, lane;\n-\tint ret;\n-\n-\tret = max96714_disable_tx_port(priv);\n-\n-\tmipi = &priv->mipi_csi2;\n-\tval = div_u64(priv->tx_link_freq * 2, MHZ(100));\n-\n-\tcci_update_bits(priv->regmap, MAX96714_BACKTOP25,\n-\t\t\tCSI_DPLL_FREQ_MASK, val, &ret);\n-\n-\tval = FIELD_PREP(MAX96714_CSI2_LANE_CNT_MASK, mipi->num_data_lanes - 1);\n-\tcci_update_bits(priv->regmap, MAX96714_MIPI_LANE_CNT,\n-\t\t\tMAX96714_CSI2_LANE_CNT_MASK, val, &ret);\n-\n-\t/* lanes polarity */\n-\tval = 0;\n-\tfor (lane = 0; lane < mipi->num_data_lanes + 1; lane++) {\n-\t\tif (!mipi->lane_polarities[lane])\n-\t\t\tcontinue;\n-\t\tif (lane == 0)\n-\t\t\t/* clock lane */\n-\t\t\tval |= BIT(5);\n-\t\telse if (lane < 3)\n-\t\t\t/* Lane D0 and D1 */\n-\t\t\tval |= BIT(lane - 1);\n-\t\telse\n-\t\t\t/* D2 and D3 */\n-\t\t\tval |= BIT(lane);\n-\t}\n-\n-\tcci_update_bits(priv->regmap, MAX96714_MIPI_POLARITY,\n-\t\t\tMAX96714_MIPI_POLARITY_MASK, val, &ret);\n-\n-\t/* lanes mapping */\n-\tval = 0;\n-\tfor (lane = 0; lane < mipi->num_data_lanes; lane++) {\n-\t\tval |= (mipi->data_lanes[lane] - 1) << (lane * 2);\n-\t\tlanes_used |= BIT(mipi->data_lanes[lane] - 1);\n-\t}\n-\n-\t/*\n-\t * Unused lanes need to be mapped as well to not have\n-\t * the same lanes mapped twice.\n-\t */\n-\tfor (; lane < MAX96714_CSI_NLANES; lane++) {\n-\t\tunsigned int idx = find_first_zero_bit(&lanes_used,\n-\t\t\t\t\t\t MAX96714_CSI_NLANES);\n-\n-\t\tval |= idx << (lane * 2);\n-\t\tlanes_used |= BIT(idx);\n-\t}\n-\n-\treturn cci_write(priv->regmap, MAX96714_MIPI_LANE_MAP, val, &ret);\n-}\n-\n-static int max96714_rxport_enable_poc(struct max96714_priv *priv)\n-{\n-\tstruct max96714_rxport *rxport = &priv->rxport;\n-\n-\tif (!rxport->poc)\n-\t\treturn 0;\n-\n-\treturn regulator_enable(rxport->poc);\n-}\n-\n-static int max96714_rxport_disable_poc(struct max96714_priv *priv)\n-{\n-\tstruct max96714_rxport *rxport = &priv->rxport;\n-\n-\tif (!rxport->poc)\n-\t\treturn 0;\n-\n-\treturn regulator_disable(rxport->poc);\n-}\n-\n-static int max96714_parse_dt_txport(struct max96714_priv *priv)\n-{\n-\tstruct device *dev = &priv->client->dev;\n-\tstruct v4l2_fwnode_endpoint vep = { .bus_type = V4L2_MBUS_CSI2_DPHY };\n-\tstruct fwnode_handle *ep_fwnode;\n-\tu32 num_data_lanes;\n-\tint ret;\n-\n-\tep_fwnode = fwnode_graph_get_endpoint_by_id(dev_fwnode(dev),\n-\t\t\t\t\t\t MAX96714_PAD_SOURCE, 0, 0);\n-\tif (!ep_fwnode)\n-\t\treturn -EINVAL;\n-\n-\tret = v4l2_fwnode_endpoint_alloc_parse(ep_fwnode, &vep);\n-\tfwnode_handle_put(ep_fwnode);\n-\tif (ret) {\n-\t\tdev_err(dev, \"tx: failed to parse endpoint data\\n\");\n-\t\treturn -EINVAL;\n-\t}\n-\n-\tif (vep.nr_of_link_frequencies != 1) {\n-\t\tret = -EINVAL;\n-\t\tgoto err_free_vep;\n-\t}\n-\n-\tpriv->tx_link_freq = vep.link_frequencies[0];\n-\t/* Min 50MHz, Max 1250MHz, 50MHz step */\n-\tif (priv->tx_link_freq < MHZ(50) || priv->tx_link_freq > MHZ(1250) ||\n-\t (u32)priv->tx_link_freq % MHZ(50)) {\n-\t\tdev_err(dev, \"tx: invalid link frequency\\n\");\n-\t\tret = -EINVAL;\n-\t\tgoto err_free_vep;\n-\t}\n-\n-\tnum_data_lanes = vep.bus.mipi_csi2.num_data_lanes;\n-\tif (num_data_lanes < 1 || num_data_lanes > MAX96714_CSI_NLANES) {\n-\t\tdev_err(dev,\n-\t\t\t\"tx: invalid number of data lanes must be 1 to 4\\n\");\n-\t\tret = -EINVAL;\n-\t\tgoto err_free_vep;\n-\t}\n-\n-\tpriv->mipi_csi2 = vep.bus.mipi_csi2;\n-\n-err_free_vep:\n-\tv4l2_fwnode_endpoint_free(&vep);\n-\n-\treturn ret;\n-}\n-\n-static int max96714_parse_dt_rxport(struct max96714_priv *priv)\n-{\n-\tstatic const char *poc_name = \"port0-poc\";\n-\tstruct max96714_rxport *rxport = &priv->rxport;\n-\tstruct device *dev = &priv->client->dev;\n-\tstruct fwnode_handle *ep_fwnode;\n-\tint ret;\n-\n-\tep_fwnode = fwnode_graph_get_endpoint_by_id(dev_fwnode(dev),\n-\t\t\t\t\t\t MAX96714_PAD_SINK, 0, 0);\n-\tif (!ep_fwnode)\n-\t\treturn -ENOENT;\n-\n-\trxport->source.ep_fwnode = fwnode_graph_get_remote_endpoint(ep_fwnode);\n-\tfwnode_handle_put(ep_fwnode);\n-\n-\tif (!rxport->source.ep_fwnode) {\n-\t\tdev_err(dev, \"rx: no remote endpoint\\n\");\n-\t\treturn -EINVAL;\n-\t}\n-\n-\trxport->poc = devm_regulator_get_optional(dev, poc_name);\n-\tif (IS_ERR(rxport->poc)) {\n-\t\tret = PTR_ERR(rxport->poc);\n-\t\tif (ret == -ENODEV) {\n-\t\t\trxport->poc = NULL;\n-\t\t} else {\n-\t\t\tdev_err(dev, \"rx: failed to get POC supply: %d\\n\", ret);\n-\t\t\tgoto err_put_source_ep_fwnode;\n-\t\t}\n-\t}\n-\n-\treturn 0;\n-\n-err_put_source_ep_fwnode:\n-\tfwnode_handle_put(rxport->source.ep_fwnode);\n-\treturn ret;\n-}\n-\n-static int max96714_parse_dt(struct max96714_priv *priv)\n-{\n-\tint ret;\n-\n-\tret = max96714_parse_dt_txport(priv);\n-\tif (ret)\n-\t\treturn ret;\n-\n-\tret = max96714_parse_dt_rxport(priv);\n-\t/*\n-\t * The deserializer can create a test pattern even if the\n-\t * rx port is not connected to a serializer.\n-\t */\n-\tif (ret && ret == -ENOENT)\n-\t\tret = 0;\n-\n-\treturn ret;\n-}\n-\n-static int max96714_enable_core_hw(struct max96714_priv *priv)\n-{\n-\tstruct device *dev = &priv->client->dev;\n-\tu64 val;\n-\tint ret;\n-\n-\tif (priv->pd_gpio) {\n-\t\t/* wait min 2 ms for reset to complete */\n-\t\tgpiod_set_value_cansleep(priv->pd_gpio, 1);\n-\t\tfsleep(2000);\n-\t\tgpiod_set_value_cansleep(priv->pd_gpio, 0);\n-\t\t/* wait min 2 ms for power up to finish */\n-\t\tfsleep(2000);\n-\t}\n-\n-\tret = cci_read(priv->regmap, MAX96714_REG13, &val, NULL);\n-\tif (ret) {\n-\t\tdev_err_probe(dev, ret, \"Cannot read first register, abort\\n\");\n-\t\tgoto err_pd_gpio;\n-\t}\n-\n-\tif (val != MAX96714_DEVICE_ID && val != MAX96714F_DEVICE_ID) {\n-\t\tdev_err(dev, \"Unsupported device id expected %x got %x\\n\",\n-\t\t\tMAX96714F_DEVICE_ID, (u8)val);\n-\t\tret = -EOPNOTSUPP;\n-\t\tgoto err_pd_gpio;\n-\t}\n-\n-\tret = cci_read(priv->regmap, MAX96714_DEV_REV, &val, NULL);\n-\tif (ret)\n-\t\tgoto err_pd_gpio;\n-\n-\tdev_dbg(dev, \"Found %x (rev %lx)\\n\", MAX96714F_DEVICE_ID,\n-\t\t(u8)val & MAX96714_DEV_REV_MASK);\n-\n-\tret = cci_read(priv->regmap, MAX96714_MIPI_TX52, &val, NULL);\n-\tif (ret)\n-\t\tgoto err_pd_gpio;\n-\n-\tif (!(val & MAX96714_TUN_EN)) {\n-\t\tdev_err(dev, \"Only supporting tunnel mode\");\n-\t\tret = -EOPNOTSUPP;\n-\t\tgoto err_pd_gpio;\n-\t}\n-\n-\treturn 0;\n-\n-err_pd_gpio:\n-\tgpiod_set_value_cansleep(priv->pd_gpio, 1);\n-\treturn ret;\n-}\n-\n-static void max96714_disable_core_hw(struct max96714_priv *priv)\n-{\n-\tgpiod_set_value_cansleep(priv->pd_gpio, 1);\n-}\n-\n-static int max96714_get_hw_resources(struct max96714_priv *priv)\n-{\n-\tstruct device *dev = &priv->client->dev;\n-\n-\tpriv->regmap = devm_cci_regmap_init_i2c(priv->client, 16);\n-\tif (IS_ERR(priv->regmap))\n-\t\treturn PTR_ERR(priv->regmap);\n-\n-\tpriv->pd_gpio =\n-\t\tdevm_gpiod_get_optional(dev, \"powerdown\", GPIOD_OUT_HIGH);\n-\tif (IS_ERR(priv->pd_gpio))\n-\t\treturn dev_err_probe(dev, PTR_ERR(priv->pd_gpio),\n-\t\t\t\t \"Cannot get powerdown GPIO\\n\");\n-\treturn 0;\n-}\n-\n-static int max96714_probe(struct i2c_client *client)\n-{\n-\tstruct device *dev = &client->dev;\n-\tstruct max96714_priv *priv;\n-\tint ret;\n-\n-\tpriv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);\n-\tif (!priv)\n-\t\treturn -ENOMEM;\n-\n-\tpriv->client = client;\n-\n-\tret = max96714_get_hw_resources(priv);\n-\tif (ret)\n-\t\treturn ret;\n-\n-\tret = max96714_enable_core_hw(priv);\n-\tif (ret)\n-\t\treturn ret;\n-\n-\tret = max96714_parse_dt(priv);\n-\tif (ret)\n-\t\tgoto err_disable_core_hw;\n-\n-\tmax96714_init_tx_port(priv);\n-\n-\tret = max96714_rxport_enable_poc(priv);\n-\tif (ret)\n-\t\tgoto err_free_ports;\n-\n-\tret = max96714_i2c_mux_init(priv);\n-\tif (ret)\n-\t\tgoto err_disable_poc;\n-\n-\tret = max96714_create_subdev(priv);\n-\tif (ret)\n-\t\tgoto err_del_mux;\n-\n-\treturn 0;\n-\n-err_del_mux:\n-\ti2c_mux_del_adapters(priv->mux);\n-err_disable_poc:\n-\tmax96714_rxport_disable_poc(priv);\n-err_free_ports:\n-\tfwnode_handle_put(priv->rxport.source.ep_fwnode);\n-err_disable_core_hw:\n-\tmax96714_disable_core_hw(priv);\n-\n-\treturn ret;\n-}\n-\n-static void max96714_remove(struct i2c_client *client)\n-{\n-\tstruct v4l2_subdev *sd = i2c_get_clientdata(client);\n-\tstruct max96714_priv *priv = sd_to_max96714(sd);\n-\n-\tmax96714_destroy_subdev(priv);\n-\ti2c_mux_del_adapters(priv->mux);\n-\tmax96714_rxport_disable_poc(priv);\n-\tfwnode_handle_put(priv->rxport.source.ep_fwnode);\n-\tmax96714_disable_core_hw(priv);\n-\tgpiod_set_value_cansleep(priv->pd_gpio, 1);\n-}\n-\n-static const struct of_device_id max96714_of_ids[] = {\n-\t{ .compatible = \"maxim,max96714f\" },\n-\t{ }\n-};\n-MODULE_DEVICE_TABLE(of, max96714_of_ids);\n-\n-static struct i2c_driver max96714_i2c_driver = {\n-\t.driver\t= {\n-\t\t.name\t\t= \"max96714\",\n-\t\t.of_match_table\t= max96714_of_ids,\n-\t},\n-\t.probe\t\t= max96714_probe,\n-\t.remove\t\t= max96714_remove,\n-};\n-\n-module_i2c_driver(max96714_i2c_driver);\n-\n-MODULE_LICENSE(\"GPL\");\n-MODULE_DESCRIPTION(\"Maxim Integrated GMSL2 Deserializers Driver\");\n-MODULE_AUTHOR(\"Julien Massot <julien.massot@collabora.com>\");\n", "prefixes": [ "v10", "22/22" ] }