Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/1.1/patches/2220313/?format=api
{ "id": 2220313, "url": "http://patchwork.ozlabs.org/api/1.1/patches/2220313/?format=api", "web_url": "http://patchwork.ozlabs.org/project/linux-gpio/patch/20260406-gmsl2-3_serdes-v10-21-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-21-645560fedca5@analog.com>", "date": "2026-04-06T20:15:00", "name": "[v10,21/22] media: i2c: remove MAX96717 driver", "commit_ref": null, "pull_url": null, "state": "new", "archived": false, "hash": "869b351902a127af0004b8503576d6b914858f7e", "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-21-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/2220313/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/2220313/checks/", "tags": {}, "headers": { "Return-Path": "\n <linux-gpio+bounces-34741-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=ls8wKIsQ;\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-34741-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=\"ls8wKIsQ\"", "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 4fqLQv0rzXz1yFt\n\tfor <incoming@patchwork.ozlabs.org>; Tue, 07 Apr 2026 06:24:39 +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 CADCD305E324\n\tfor <incoming@patchwork.ozlabs.org>; Mon, 6 Apr 2026 20:16:25 +0000 (UTC)", "from localhost.localdomain (localhost.localdomain [127.0.0.1])\n\tby smtp.subspace.kernel.org (Postfix) with ESMTP id 3F56C3A4F31;\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 097433A16A8;\n\tMon, 6 Apr 2026 20:15:23 +0000 (UTC)", "by smtp.kernel.org (Postfix) with ESMTPS id E1C09C2BCB0;\n\tMon, 6 Apr 2026 20:15:22 +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 D99DFFB5165;\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=XAPR0g0VeC+iZYhtA1odoWz/OAbc29t/IiXoq2WFwSPqYPArrsfsyoq2xxU29ZDB6Z93qcQNkcLpyVaNDGI2yBa3ejetipsOId5jEoZIVVR9FbA7XyF1NH4vvElF0OHPpPMSSKwIC5JyjdIwsFPIsb87GXbsCSKPK1cI14bZf3s=", "ARC-Message-Signature": "i=1; a=rsa-sha256; d=subspace.kernel.org;\n\ts=arc-20240116; t=1775506523; c=relaxed/simple;\n\tbh=ZG9IgX20HXJfYlGi/so2ijFG06FqEPsjqrUBL6hkgX8=;\n\th=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References:\n\t In-Reply-To:To:Cc;\n b=UmocGE5bdqsPev6lU1tTnYeueIXiQAgYf7o5q0Kg8cP0cNfNcT9gTjL2l/PJoinxn12Hn58pei9dq+EoVo8CXGS3fH27BSOuvE33U784kTBysxPSuhim8ASn3AD+QiP1fgaXumT3lhXr32Eo2x/BdF5cv/X5OQyW+26eTJy+jd4=", "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=ls8wKIsQ; 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=1775506522;\n\tbh=ZG9IgX20HXJfYlGi/so2ijFG06FqEPsjqrUBL6hkgX8=;\n\th=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From;\n\tb=ls8wKIsQwA4IlLEYxzdm+LcxyaQglmtnA4fNAL5Lrlh7migYW9nxPujURgg3+pEh4\n\t 7syAU90IXN3HNDk+EpvBBbFIVd6GyQ8n8Zo/SV7ATIVVXdNkIrdujhBkzKDUuLInVu\n\t /f00o5pCv0VxamkrDCHDVg5aNCr3wjonck8aqFpXuKiUiuiPRPecQlL4ZWyhUEEbbK\n\t tCR+0sP2s+zmQwMNNAuTaymbwheZCVP/fkOYqYAI6xD3DaBl2ewC+4f2EAGPc9OMrZ\n\t JQNc3fyn/oxYi87BBNjvPClzR7z/FGNktGm2DytnhfvokbXshS8SBNf8rUeJw0wx3h\n\t WoqovO2/zGMqA==", "From": "Dumitru Ceclan via B4 Relay\n <devnull+dumitru.ceclan.analog.com@kernel.org>", "Date": "Mon, 06 Apr 2026 23:15:00 +0300", "Subject": "[PATCH v10 21/22] media: i2c: remove MAX96717 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-21-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=34734;\n i=dumitru.ceclan@analog.com; s=20240313; h=from:subject:message-id;\n bh=woCcj1vj7yOoZltqJEKo3Xh8Q7gbajNCB0vQLd0N37E=;\n b=OUeKsUIyUP/WD+hIdTr0EsOgx/QuFyF3+Uefko1CTLPhOwvbgNCx6hhPFFtLL4SuH01se48hp\n b+GuwnIpAwfCZ0O84eRBIHelKg2Fz36fiwpW5NoswwkRG4EnifcU+Np", "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 MAX96717 driver. Its functionality has been moved to a new\nMAX96717 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/max96717.c | 1102 ------------------------------------------\n 4 files changed, 1121 deletions(-)", "diff": "diff --git a/MAINTAINERS b/MAINTAINERS\nindex 6a6a04ce2787..ad7e28897062 100644\n--- a/MAINTAINERS\n+++ b/MAINTAINERS\n@@ -15235,7 +15235,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,max96717.yaml\n-F:\tdrivers/media/i2c/max96717.c\n \n MAX9860 MONO AUDIO VOICE CODEC DRIVER\n M:\tPeter Rosin <peda@axentia.se>\ndiff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig\nindex 37f86e6de969..20a2261b64f9 100644\n--- a/drivers/media/i2c/Kconfig\n+++ b/drivers/media/i2c/Kconfig\n@@ -1701,23 +1701,6 @@ config VIDEO_MAX96714\n \t To compile this driver as a module, choose M here: the\n \t module will be called max96714.\n \n-config VIDEO_MAX96717\n-\ttristate \"Maxim MAX96717 GMSL2 Serializer support\"\n-\tdepends on I2C && VIDEO_DEV && COMMON_CLK\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 MAX96717 GMSL2 Serializer.\n-\t MAX96717 serializers convert video on a MIPI CSI-2\n-\t input to a GMSL2 output.\n-\n-\t To compile this driver as a module, choose M here: the\n-\t module will be called max96717.\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 be3200b23819..96bc49339341 100644\n--- a/drivers/media/i2c/Makefile\n+++ b/drivers/media/i2c/Makefile\n@@ -70,7 +70,6 @@ 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_MAX96717) += max96717.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/max96717.c b/drivers/media/i2c/max96717.c\ndeleted file mode 100644\nindex c8ae7890d9fa..000000000000\n--- a/drivers/media/i2c/max96717.c\n+++ /dev/null\n@@ -1,1102 +0,0 @@\n-// SPDX-License-Identifier: GPL-2.0\n-/*\n- * Maxim GMSL2 Serializer Driver\n- *\n- * Copyright (C) 2024 Collabora Ltd.\n- */\n-\n-#include <linux/bitfield.h>\n-#include <linux/clk.h>\n-#include <linux/clk-provider.h>\n-#include <linux/delay.h>\n-#include <linux/gpio/driver.h>\n-#include <linux/i2c-mux.h>\n-#include <linux/i2c.h>\n-#include <linux/property.h>\n-#include <linux/regmap.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 MAX96717_DEVICE_ID 0xbf\n-#define MAX96717F_DEVICE_ID 0xc8\n-#define MAX96717_PORTS 2\n-#define MAX96717_PAD_SINK 0\n-#define MAX96717_PAD_SOURCE 1\n-#define MAX96717_CSI_NLANES 4\n-\n-#define MAX96717_DEFAULT_CLKOUT_RATE\t24000000UL\n-\n-/* DEV */\n-#define MAX96717_REG3 CCI_REG8(0x3)\n-#define MAX96717_RCLKSEL GENMASK(1, 0)\n-#define RCLKSEL_REF_PLL CCI_REG8(0x3)\n-#define MAX96717_REG6 CCI_REG8(0x6)\n-#define RCLKEN BIT(5)\n-#define MAX96717_DEV_ID CCI_REG8(0xd)\n-#define MAX96717_DEV_REV CCI_REG8(0xe)\n-#define MAX96717_DEV_REV_MASK GENMASK(3, 0)\n-\n-/* VID_TX Z */\n-#define MAX96717_VIDEO_TX0 CCI_REG8(0x110)\n-#define MAX96717_VIDEO_AUTO_BPP BIT(3)\n-#define MAX96717_VIDEO_TX2 CCI_REG8(0x112)\n-#define MAX96717_VIDEO_PCLKDET BIT(7)\n-\n-/* VTX_Z */\n-#define MAX96717_VTX0 CCI_REG8(0x24e)\n-#define MAX96717_VTX1 CCI_REG8(0x24f)\n-#define MAX96717_PATTERN_CLK_FREQ GENMASK(3, 1)\n-#define MAX96717_VTX_VS_DLY CCI_REG24(0x250)\n-#define MAX96717_VTX_VS_HIGH CCI_REG24(0x253)\n-#define MAX96717_VTX_VS_LOW CCI_REG24(0x256)\n-#define MAX96717_VTX_V2H CCI_REG24(0x259)\n-#define MAX96717_VTX_HS_HIGH CCI_REG16(0x25c)\n-#define MAX96717_VTX_HS_LOW CCI_REG16(0x25e)\n-#define MAX96717_VTX_HS_CNT CCI_REG16(0x260)\n-#define MAX96717_VTX_V2D CCI_REG24(0x262)\n-#define MAX96717_VTX_DE_HIGH CCI_REG16(0x265)\n-#define MAX96717_VTX_DE_LOW CCI_REG16(0x267)\n-#define MAX96717_VTX_DE_CNT CCI_REG16(0x269)\n-#define MAX96717_VTX29 CCI_REG8(0x26b)\n-#define MAX96717_VTX_MODE GENMASK(1, 0)\n-#define MAX96717_VTX_GRAD_INC CCI_REG8(0x26c)\n-#define MAX96717_VTX_CHKB_COLOR_A CCI_REG24(0x26d)\n-#define MAX96717_VTX_CHKB_COLOR_B CCI_REG24(0x270)\n-#define MAX96717_VTX_CHKB_RPT_CNT_A CCI_REG8(0x273)\n-#define MAX96717_VTX_CHKB_RPT_CNT_B CCI_REG8(0x274)\n-#define MAX96717_VTX_CHKB_ALT CCI_REG8(0x275)\n-\n-/* GPIO */\n-#define MAX96717_NUM_GPIO 11\n-#define MAX96717_GPIO_REG_A(gpio) CCI_REG8(0x2be + (gpio) * 3)\n-#define MAX96717_GPIO_OUT BIT(4)\n-#define MAX96717_GPIO_IN BIT(3)\n-#define MAX96717_GPIO_RX_EN BIT(2)\n-#define MAX96717_GPIO_TX_EN BIT(1)\n-#define MAX96717_GPIO_OUT_DIS BIT(0)\n-\n-/* FRONTTOP */\n-/* MAX96717 only have CSI port 'B' */\n-#define MAX96717_FRONTOP0 CCI_REG8(0x308)\n-#define MAX96717_START_PORT_B BIT(5)\n-\n-/* MIPI_RX */\n-#define MAX96717_MIPI_RX1 CCI_REG8(0x331)\n-#define MAX96717_MIPI_LANES_CNT GENMASK(5, 4)\n-#define MAX96717_MIPI_RX2 CCI_REG8(0x332) /* phy1 Lanes map */\n-#define MAX96717_PHY2_LANES_MAP GENMASK(7, 4)\n-#define MAX96717_MIPI_RX3 CCI_REG8(0x333) /* phy2 Lanes map */\n-#define MAX96717_PHY1_LANES_MAP GENMASK(3, 0)\n-#define MAX96717_MIPI_RX4 CCI_REG8(0x334) /* phy1 lane polarities */\n-#define MAX96717_PHY1_LANES_POL GENMASK(6, 4)\n-#define MAX96717_MIPI_RX5 CCI_REG8(0x335) /* phy2 lane polarities */\n-#define MAX96717_PHY2_LANES_POL GENMASK(2, 0)\n-\n-/* MIPI_RX_EXT */\n-#define MAX96717_MIPI_RX_EXT11 CCI_REG8(0x383)\n-#define MAX96717_TUN_MODE BIT(7)\n-\n-/* REF_VTG */\n-#define REF_VTG0 CCI_REG8(0x3f0)\n-#define REFGEN_PREDEF_EN BIT(6)\n-#define REFGEN_PREDEF_FREQ_MASK GENMASK(5, 4)\n-#define REFGEN_PREDEF_FREQ_ALT BIT(3)\n-#define REFGEN_RST BIT(1)\n-#define REFGEN_EN BIT(0)\n-\n-/* MISC */\n-#define PIO_SLEW_1 CCI_REG8(0x570)\n-\n-enum max96717_vpg_mode {\n-\tMAX96717_VPG_DISABLED = 0,\n-\tMAX96717_VPG_CHECKERBOARD = 1,\n-\tMAX96717_VPG_GRADIENT = 2,\n-};\n-\n-struct max96717_priv {\n-\tstruct i2c_client\t\t *client;\n-\tstruct regmap\t\t\t *regmap;\n-\tstruct i2c_mux_core\t\t *mux;\n-\tstruct v4l2_mbus_config_mipi_csi2 mipi_csi2;\n-\tstruct v4l2_subdev sd;\n-\tstruct media_pad pads[MAX96717_PORTS];\n-\tstruct v4l2_ctrl_handler ctrl_handler;\n-\tstruct v4l2_async_notifier notifier;\n-\tstruct v4l2_subdev *source_sd;\n-\tu16 source_sd_pad;\n-\tu64\t\t\t enabled_source_streams;\n-\tu8 pll_predef_index;\n-\tstruct clk_hw clk_hw;\n-\tstruct gpio_chip gpio_chip;\n-\tenum max96717_vpg_mode pattern;\n-};\n-\n-static inline struct max96717_priv *sd_to_max96717(struct v4l2_subdev *sd)\n-{\n-\treturn container_of(sd, struct max96717_priv, sd);\n-}\n-\n-static inline struct max96717_priv *clk_hw_to_max96717(struct clk_hw *hw)\n-{\n-\treturn container_of(hw, struct max96717_priv, clk_hw);\n-}\n-\n-static int max96717_i2c_mux_select(struct i2c_mux_core *mux, u32 chan)\n-{\n-\treturn 0;\n-}\n-\n-static int max96717_i2c_mux_init(struct max96717_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 max96717_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 inline int max96717_start_csi(struct max96717_priv *priv, bool start)\n-{\n-\treturn cci_update_bits(priv->regmap, MAX96717_FRONTOP0,\n-\t\t\t MAX96717_START_PORT_B,\n-\t\t\t start ? MAX96717_START_PORT_B : 0, NULL);\n-}\n-\n-static int max96717_apply_patgen_timing(struct max96717_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, MAX96717_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, MAX96717_VTX1,\n-\t\t\tMAX96717_PATTERN_CLK_FREQ, 0xa, &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, MAX96717_VTX_VS_DLY, 0, &ret);\n-\tcci_write(priv->regmap, MAX96717_VTX_VS_HIGH, v_sw * h_tot, &ret);\n-\tcci_write(priv->regmap, MAX96717_VTX_VS_LOW,\n-\t\t (v_active + v_fp + v_bp) * h_tot, &ret);\n-\tcci_write(priv->regmap, MAX96717_VTX_HS_HIGH, h_sw, &ret);\n-\tcci_write(priv->regmap, MAX96717_VTX_HS_LOW, h_active + h_fp + h_bp,\n-\t\t &ret);\n-\tcci_write(priv->regmap, MAX96717_VTX_V2D,\n-\t\t h_tot * (v_sw + v_bp) + (h_sw + h_bp), &ret);\n-\tcci_write(priv->regmap, MAX96717_VTX_HS_CNT, v_tot, &ret);\n-\tcci_write(priv->regmap, MAX96717_VTX_DE_HIGH, h_active, &ret);\n-\tcci_write(priv->regmap, MAX96717_VTX_DE_LOW, h_fp + h_sw + h_bp,\n-\t\t &ret);\n-\tcci_write(priv->regmap, MAX96717_VTX_DE_CNT, v_active, &ret);\n-\t/* B G R */\n-\tcci_write(priv->regmap, MAX96717_VTX_CHKB_COLOR_A, 0xfecc00, &ret);\n-\t/* B G R */\n-\tcci_write(priv->regmap, MAX96717_VTX_CHKB_COLOR_B, 0x006aa7, &ret);\n-\tcci_write(priv->regmap, MAX96717_VTX_CHKB_RPT_CNT_A, 0x3c, &ret);\n-\tcci_write(priv->regmap, MAX96717_VTX_CHKB_RPT_CNT_B, 0x3c, &ret);\n-\tcci_write(priv->regmap, MAX96717_VTX_CHKB_ALT, 0x3c, &ret);\n-\tcci_write(priv->regmap, MAX96717_VTX_GRAD_INC, 0x10, &ret);\n-\n-\treturn ret;\n-}\n-\n-static int max96717_apply_patgen(struct max96717_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 = max96717_apply_patgen_timing(priv, state);\n-\n-\tcci_write(priv->regmap, MAX96717_VTX0, priv->pattern ? 0xfb : 0,\n-\t\t &ret);\n-\n-\tval = FIELD_PREP(MAX96717_VTX_MODE, priv->pattern);\n-\tcci_update_bits(priv->regmap, MAX96717_VTX29, MAX96717_VTX_MODE,\n-\t\t\tval, &ret);\n-\treturn ret;\n-}\n-\n-static int max96717_s_ctrl(struct v4l2_ctrl *ctrl)\n-{\n-\tstruct max96717_priv *priv =\n-\t\tcontainer_of(ctrl->handler, struct max96717_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-\t/* Use bpp from bpp register */\n-\tret = cci_update_bits(priv->regmap, MAX96717_VIDEO_TX0,\n-\t\t\t MAX96717_VIDEO_AUTO_BPP,\n-\t\t\t priv->pattern ? 0 : MAX96717_VIDEO_AUTO_BPP,\n-\t\t\t NULL);\n-\n-\t/*\n-\t * Pattern generator doesn't work with tunnel mode.\n-\t * Needs RGB color format and deserializer tunnel mode must be disabled.\n-\t */\n-\treturn cci_update_bits(priv->regmap, MAX96717_MIPI_RX_EXT11,\n-\t\t\t MAX96717_TUN_MODE,\n-\t\t\t priv->pattern ? 0 : MAX96717_TUN_MODE, &ret);\n-}\n-\n-static const char * const max96717_test_pattern[] = {\n-\t\"Disabled\",\n-\t\"Checkerboard\",\n-\t\"Gradient\"\n-};\n-\n-static const struct v4l2_ctrl_ops max96717_ctrl_ops = {\n-\t.s_ctrl = max96717_s_ctrl,\n-};\n-\n-static int max96717_gpiochip_get(struct gpio_chip *gpiochip,\n-\t\t\t\t unsigned int offset)\n-{\n-\tstruct max96717_priv *priv = gpiochip_get_data(gpiochip);\n-\tu64 val;\n-\tint ret;\n-\n-\tret = cci_read(priv->regmap, MAX96717_GPIO_REG_A(offset),\n-\t\t &val, NULL);\n-\tif (ret)\n-\t\treturn ret;\n-\n-\tif (val & MAX96717_GPIO_OUT_DIS)\n-\t\treturn !!(val & MAX96717_GPIO_IN);\n-\telse\n-\t\treturn !!(val & MAX96717_GPIO_OUT);\n-}\n-\n-static int max96717_gpiochip_set(struct gpio_chip *gpiochip,\n-\t\t\t\t unsigned int offset, int value)\n-{\n-\tstruct max96717_priv *priv = gpiochip_get_data(gpiochip);\n-\n-\treturn cci_update_bits(priv->regmap, MAX96717_GPIO_REG_A(offset),\n-\t\t\t MAX96717_GPIO_OUT, MAX96717_GPIO_OUT, NULL);\n-}\n-\n-static int max96717_gpio_get_direction(struct gpio_chip *gpiochip,\n-\t\t\t\t unsigned int offset)\n-{\n-\tstruct max96717_priv *priv = gpiochip_get_data(gpiochip);\n-\tu64 val;\n-\tint ret;\n-\n-\tret = cci_read(priv->regmap, MAX96717_GPIO_REG_A(offset), &val, NULL);\n-\tif (ret < 0)\n-\t\treturn ret;\n-\n-\treturn !!(val & MAX96717_GPIO_OUT_DIS);\n-}\n-\n-static int max96717_gpio_direction_out(struct gpio_chip *gpiochip,\n-\t\t\t\t unsigned int offset, int value)\n-{\n-\tstruct max96717_priv *priv = gpiochip_get_data(gpiochip);\n-\n-\treturn cci_update_bits(priv->regmap, MAX96717_GPIO_REG_A(offset),\n-\t\t\t MAX96717_GPIO_OUT_DIS | MAX96717_GPIO_OUT,\n-\t\t\t value ? MAX96717_GPIO_OUT : 0, NULL);\n-}\n-\n-static int max96717_gpio_direction_in(struct gpio_chip *gpiochip,\n-\t\t\t\t unsigned int offset)\n-{\n-\tstruct max96717_priv *priv = gpiochip_get_data(gpiochip);\n-\n-\treturn cci_update_bits(priv->regmap, MAX96717_GPIO_REG_A(offset),\n-\t\t\t MAX96717_GPIO_OUT_DIS, MAX96717_GPIO_OUT_DIS,\n-\t\t\t NULL);\n-}\n-\n-static int max96717_gpiochip_probe(struct max96717_priv *priv)\n-{\n-\tstruct device *dev = &priv->client->dev;\n-\tstruct gpio_chip *gc = &priv->gpio_chip;\n-\tint i, ret = 0;\n-\n-\tgc->label = dev_name(dev);\n-\tgc->parent = dev;\n-\tgc->owner = THIS_MODULE;\n-\tgc->ngpio = MAX96717_NUM_GPIO;\n-\tgc->base = -1;\n-\tgc->can_sleep = true;\n-\tgc->get_direction = max96717_gpio_get_direction;\n-\tgc->direction_input = max96717_gpio_direction_in;\n-\tgc->direction_output = max96717_gpio_direction_out;\n-\tgc->set = max96717_gpiochip_set;\n-\tgc->get = max96717_gpiochip_get;\n-\n-\t/* Disable GPIO forwarding */\n-\tfor (i = 0; i < gc->ngpio; i++)\n-\t\tcci_update_bits(priv->regmap, MAX96717_GPIO_REG_A(i),\n-\t\t\t\tMAX96717_GPIO_RX_EN | MAX96717_GPIO_TX_EN,\n-\t\t\t\t0, &ret);\n-\n-\tif (ret)\n-\t\treturn ret;\n-\n-\tret = devm_gpiochip_add_data(dev, gc, priv);\n-\tif (ret) {\n-\t\tdev_err(dev, \"Unable to create gpio_chip\\n\");\n-\t\treturn ret;\n-\t}\n-\n-\treturn 0;\n-}\n-\n-static int _max96717_set_routing(struct v4l2_subdev *sd,\n-\t\t\t\t struct v4l2_subdev_state *state,\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-\tret = v4l2_subdev_set_routing_with_fmt(sd, state, routing, &format);\n-\tif (ret)\n-\t\treturn ret;\n-\n-\treturn 0;\n-}\n-\n-static int max96717_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 max96717_priv *priv = sd_to_max96717(sd);\n-\n-\tif (which == V4L2_SUBDEV_FORMAT_ACTIVE && priv->enabled_source_streams)\n-\t\treturn -EBUSY;\n-\n-\treturn _max96717_set_routing(sd, state, routing);\n-}\n-\n-static int max96717_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 max96717_priv *priv = sd_to_max96717(sd);\n-\tstruct v4l2_mbus_framefmt *fmt;\n-\tu64 stream_source_mask;\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 == MAX96717_PAD_SOURCE)\n-\t\treturn v4l2_subdev_get_fmt(sd, state, format);\n-\n-\t/* Set sink format */\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-\t/* Propagate to source format */\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-\t*fmt = format->format;\n-\n-\tstream_source_mask = BIT(format->stream);\n-\n-\treturn v4l2_subdev_state_xlate_streams(state, MAX96717_PAD_SOURCE,\n-\t\t\t\t\t MAX96717_PAD_SINK,\n-\t\t\t\t\t &stream_source_mask);\n-}\n-\n-static int max96717_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 = MAX96717_PAD_SINK,\n-\t\t\t.sink_stream = 0,\n-\t\t\t.source_pad = MAX96717_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 _max96717_set_routing(sd, state, &routing);\n-}\n-\n-static bool max96717_pipe_pclkdet(struct max96717_priv *priv)\n-{\n-\tu64 val = 0;\n-\n-\tcci_read(priv->regmap, MAX96717_VIDEO_TX2, &val, NULL);\n-\n-\treturn val & MAX96717_VIDEO_PCLKDET;\n-}\n-\n-static int max96717_log_status(struct v4l2_subdev *sd)\n-{\n-\tstruct max96717_priv *priv = sd_to_max96717(sd);\n-\tstruct device *dev = &priv->client->dev;\n-\n-\tdev_info(dev, \"Serializer: max96717\\n\");\n-\tdev_info(dev, \"Pipe: pclkdet:%d\\n\", max96717_pipe_pclkdet(priv));\n-\n-\treturn 0;\n-}\n-\n-static int max96717_enable_streams(struct v4l2_subdev *sd,\n-\t\t\t\t struct v4l2_subdev_state *state, u32 pad,\n-\t\t\t\t u64 streams_mask)\n-{\n-\tstruct max96717_priv *priv = sd_to_max96717(sd);\n-\tu64 sink_streams;\n-\tint ret;\n-\n-\tif (!priv->enabled_source_streams)\n-\t\tmax96717_start_csi(priv, true);\n-\n-\tret = max96717_apply_patgen(priv, state);\n-\tif (ret)\n-\t\tgoto stop_csi;\n-\n-\tif (!priv->pattern) {\n-\t\tsink_streams =\n-\t\t\tv4l2_subdev_state_xlate_streams(state,\n-\t\t\t\t\t\t\tMAX96717_PAD_SOURCE,\n-\t\t\t\t\t\t\tMAX96717_PAD_SINK,\n-\t\t\t\t\t\t\t&streams_mask);\n-\n-\t\tret = v4l2_subdev_enable_streams(priv->source_sd,\n-\t\t\t\t\t\t priv->source_sd_pad,\n-\t\t\t\t\t\t sink_streams);\n-\t\tif (ret)\n-\t\t\tgoto stop_csi;\n-\t}\n-\n-\tpriv->enabled_source_streams |= streams_mask;\n-\n-\treturn 0;\n-\n-stop_csi:\n-\tif (!priv->enabled_source_streams)\n-\t\tmax96717_start_csi(priv, false);\n-\n-\treturn ret;\n-}\n-\n-static int max96717_disable_streams(struct v4l2_subdev *sd,\n-\t\t\t\t struct v4l2_subdev_state *state, u32 pad,\n-\t\t\t\t u64 streams_mask)\n-{\n-\tstruct max96717_priv *priv = sd_to_max96717(sd);\n-\tu64 sink_streams;\n-\n-\t/*\n-\t * Stop the CSI receiver first then the source,\n-\t * otherwise the device may become unresponsive\n-\t * while holding the I2C bus low.\n-\t */\n-\tpriv->enabled_source_streams &= ~streams_mask;\n-\tif (!priv->enabled_source_streams)\n-\t\tmax96717_start_csi(priv, false);\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\tMAX96717_PAD_SOURCE,\n-\t\t\t\t\t\t\tMAX96717_PAD_SINK,\n-\t\t\t\t\t\t\t&streams_mask);\n-\n-\t\tret = v4l2_subdev_disable_streams(priv->source_sd,\n-\t\t\t\t\t\t priv->source_sd_pad,\n-\t\t\t\t\t\t sink_streams);\n-\t\tif (ret)\n-\t\t\treturn ret;\n-\t}\n-\n-\treturn 0;\n-}\n-\n-static const struct v4l2_subdev_pad_ops max96717_pad_ops = {\n-\t.enable_streams = max96717_enable_streams,\n-\t.disable_streams = max96717_disable_streams,\n-\t.set_routing = max96717_set_routing,\n-\t.get_fmt = v4l2_subdev_get_fmt,\n-\t.set_fmt = max96717_set_fmt,\n-};\n-\n-static const struct v4l2_subdev_core_ops max96717_subdev_core_ops = {\n-\t.log_status = max96717_log_status,\n-};\n-\n-static const struct v4l2_subdev_internal_ops max96717_internal_ops = {\n-\t.init_state = max96717_init_state,\n-};\n-\n-static const struct v4l2_subdev_ops max96717_subdev_ops = {\n-\t.core = &max96717_subdev_core_ops,\n-\t.pad = &max96717_pad_ops,\n-};\n-\n-static const struct media_entity_operations max96717_entity_ops = {\n-\t.link_validate = v4l2_subdev_link_validate,\n-};\n-\n-static int max96717_notify_bound(struct v4l2_async_notifier *notifier,\n-\t\t\t\t struct v4l2_subdev *source_subdev,\n-\t\t\t\t struct v4l2_async_connection *asd)\n-{\n-\tstruct max96717_priv *priv = sd_to_max96717(notifier->sd);\n-\tstruct device *dev = &priv->client->dev;\n-\tint ret;\n-\n-\tret = media_entity_get_fwnode_pad(&source_subdev->entity,\n-\t\t\t\t\t source_subdev->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\",\n-\t\t\tsource_subdev->name);\n-\t\treturn ret;\n-\t}\n-\n-\tpriv->source_sd = source_subdev;\n-\tpriv->source_sd_pad = ret;\n-\n-\tret = media_create_pad_link(&source_subdev->entity, priv->source_sd_pad,\n-\t\t\t\t &priv->sd.entity, 0,\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:0\\n\",\n-\t\t\tsource_subdev->name, priv->source_sd_pad,\n-\t\t\tpriv->sd.name);\n-\t\treturn ret;\n-\t}\n-\n-\treturn 0;\n-}\n-\n-static const struct v4l2_async_notifier_operations max96717_notify_ops = {\n-\t.bound = max96717_notify_bound,\n-};\n-\n-static int max96717_v4l2_notifier_register(struct max96717_priv *priv)\n-{\n-\tstruct device *dev = &priv->client->dev;\n-\tstruct v4l2_async_connection *asd;\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 MAX96717_PAD_SINK, 0, 0);\n-\tif (!ep_fwnode) {\n-\t\tdev_err(dev, \"No graph endpoint\\n\");\n-\t\treturn -ENODEV;\n-\t}\n-\n-\tv4l2_async_subdev_nf_init(&priv->notifier, &priv->sd);\n-\n-\tasd = v4l2_async_nf_add_fwnode_remote(&priv->notifier, ep_fwnode,\n-\t\t\t\t\t struct v4l2_async_connection);\n-\n-\tfwnode_handle_put(ep_fwnode);\n-\n-\tif (IS_ERR(asd)) {\n-\t\tdev_err(dev, \"Failed to add subdev: %ld\", PTR_ERR(asd));\n-\t\tv4l2_async_nf_cleanup(&priv->notifier);\n-\t\treturn PTR_ERR(asd);\n-\t}\n-\n-\tpriv->notifier.ops = &max96717_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 max96717_subdev_init(struct max96717_priv *priv)\n-{\n-\tstruct device *dev = &priv->client->dev;\n-\tint ret;\n-\n-\tv4l2_i2c_subdev_init(&priv->sd, priv->client, &max96717_subdev_ops);\n-\tpriv->sd.internal_ops = &max96717_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_std_menu_items(&priv->ctrl_handler,\n-\t\t\t\t &max96717_ctrl_ops,\n-\t\t\t\t V4L2_CID_TEST_PATTERN,\n-\t\t\t\t ARRAY_SIZE(max96717_test_pattern) - 1,\n-\t\t\t\t 0, 0, max96717_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 = &max96717_entity_ops;\n-\n-\tpriv->pads[MAX96717_PAD_SINK].flags = MEDIA_PAD_FL_SINK;\n-\tpriv->pads[MAX96717_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;\n-\n-\tret = media_entity_pads_init(&priv->sd.entity, 2, priv->pads);\n-\tif (ret) {\n-\t\tdev_err_probe(dev, ret, \"Failed to init pads\\n\");\n-\t\tgoto err_free_ctrl;\n-\t}\n-\n-\tret = v4l2_subdev_init_finalize(&priv->sd);\n-\tif (ret) {\n-\t\tdev_err_probe(dev, ret,\n-\t\t\t \"v4l2 subdev init finalized failed\\n\");\n-\t\tgoto err_entity_cleanup;\n-\t}\n-\tret = max96717_v4l2_notifier_register(priv);\n-\tif (ret) {\n-\t\tdev_err_probe(dev, ret,\n-\t\t\t \"v4l2 subdev notifier register failed\\n\");\n-\t\tgoto err_free_state;\n-\t}\n-\n-\tret = v4l2_async_register_subdev(&priv->sd);\n-\tif (ret) {\n-\t\tdev_err_probe(dev, ret, \"v4l2_async_register_subdev error\\n\");\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_free_state:\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 max96717_subdev_uninit(struct max96717_priv *priv)\n-{\n-\tv4l2_async_unregister_subdev(&priv->sd);\n-\tv4l2_async_nf_unregister(&priv->notifier);\n-\tv4l2_async_nf_cleanup(&priv->notifier);\n-\tv4l2_subdev_cleanup(&priv->sd);\n-\tmedia_entity_cleanup(&priv->sd.entity);\n-\tv4l2_ctrl_handler_free(&priv->ctrl_handler);\n-}\n-\n-struct max96717_pll_predef_freq {\n-\tunsigned long freq;\n-\tbool is_alt;\n-\tu8 val;\n-};\n-\n-static const struct max96717_pll_predef_freq max96717_predef_freqs[] = {\n-\t{ 13500000, true, 0 }, { 19200000, false, 0 },\n-\t{ 24000000, true, 1 }, { 27000000, false, 1 },\n-\t{ 37125000, false, 2 }, { 74250000, false, 3 },\n-};\n-\n-static unsigned long\n-max96717_clk_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)\n-{\n-\tstruct max96717_priv *priv = clk_hw_to_max96717(hw);\n-\n-\treturn max96717_predef_freqs[priv->pll_predef_index].freq;\n-}\n-\n-static unsigned int max96717_clk_find_best_index(struct max96717_priv *priv,\n-\t\t\t\t\t\t unsigned long rate)\n-{\n-\tunsigned int i, idx = 0;\n-\tunsigned long diff_new, diff_old = U32_MAX;\n-\n-\tfor (i = 0; i < ARRAY_SIZE(max96717_predef_freqs); i++) {\n-\t\tdiff_new = abs(rate - max96717_predef_freqs[i].freq);\n-\t\tif (diff_new < diff_old) {\n-\t\t\tdiff_old = diff_new;\n-\t\t\tidx = i;\n-\t\t}\n-\t}\n-\n-\treturn idx;\n-}\n-\n-static long max96717_clk_round_rate(struct clk_hw *hw, unsigned long rate,\n-\t\t\t\t unsigned long *parent_rate)\n-{\n-\tstruct max96717_priv *priv = clk_hw_to_max96717(hw);\n-\tstruct device *dev = &priv->client->dev;\n-\tunsigned int idx;\n-\n-\tidx = max96717_clk_find_best_index(priv, rate);\n-\n-\tif (rate != max96717_predef_freqs[idx].freq) {\n-\t\tdev_warn(dev, \"Request CLK freq:%lu, found CLK freq:%lu\\n\",\n-\t\t\t rate, max96717_predef_freqs[idx].freq);\n-\t}\n-\n-\treturn max96717_predef_freqs[idx].freq;\n-}\n-\n-static int max96717_clk_set_rate(struct clk_hw *hw, unsigned long rate,\n-\t\t\t\t unsigned long parent_rate)\n-{\n-\tstruct max96717_priv *priv = clk_hw_to_max96717(hw);\n-\tunsigned int val, idx;\n-\tint ret = 0;\n-\n-\tidx = max96717_clk_find_best_index(priv, rate);\n-\n-\tval = FIELD_PREP(REFGEN_PREDEF_FREQ_MASK,\n-\t\t\t max96717_predef_freqs[idx].val);\n-\n-\tif (max96717_predef_freqs[idx].is_alt)\n-\t\tval |= REFGEN_PREDEF_FREQ_ALT;\n-\n-\tval |= REFGEN_RST | REFGEN_PREDEF_EN;\n-\n-\tcci_write(priv->regmap, REF_VTG0, val, &ret);\n-\tcci_update_bits(priv->regmap, REF_VTG0, REFGEN_RST | REFGEN_EN,\n-\t\t\tREFGEN_EN, &ret);\n-\tif (ret)\n-\t\treturn ret;\n-\n-\tpriv->pll_predef_index = idx;\n-\n-\treturn 0;\n-}\n-\n-static int max96717_clk_prepare(struct clk_hw *hw)\n-{\n-\tstruct max96717_priv *priv = clk_hw_to_max96717(hw);\n-\n-\treturn cci_update_bits(priv->regmap, MAX96717_REG6, RCLKEN,\n-\t\t\t RCLKEN, NULL);\n-}\n-\n-static void max96717_clk_unprepare(struct clk_hw *hw)\n-{\n-\tstruct max96717_priv *priv = clk_hw_to_max96717(hw);\n-\n-\tcci_update_bits(priv->regmap, MAX96717_REG6, RCLKEN, 0, NULL);\n-}\n-\n-static const struct clk_ops max96717_clk_ops = {\n-\t.prepare = max96717_clk_prepare,\n-\t.unprepare = max96717_clk_unprepare,\n-\t.set_rate = max96717_clk_set_rate,\n-\t.recalc_rate = max96717_clk_recalc_rate,\n-\t.round_rate = max96717_clk_round_rate,\n-};\n-\n-static int max96717_register_clkout(struct max96717_priv *priv)\n-{\n-\tstruct device *dev = &priv->client->dev;\n-\tstruct clk_init_data init = { .ops = &max96717_clk_ops };\n-\tint ret;\n-\n-\tinit.name = kasprintf(GFP_KERNEL, \"max96717.%s.clk_out\", dev_name(dev));\n-\tif (!init.name)\n-\t\treturn -ENOMEM;\n-\n-\t/* RCLKSEL Reference PLL output */\n-\tret = cci_update_bits(priv->regmap, MAX96717_REG3, MAX96717_RCLKSEL,\n-\t\t\t MAX96717_RCLKSEL, NULL);\n-\t/* MFP4 fastest slew rate */\n-\tcci_update_bits(priv->regmap, PIO_SLEW_1, BIT(5) | BIT(4), 0, &ret);\n-\tif (ret)\n-\t\tgoto free_init_name;\n-\n-\tpriv->clk_hw.init = &init;\n-\n-\t/* Initialize to 24 MHz */\n-\tret = max96717_clk_set_rate(&priv->clk_hw,\n-\t\t\t\t MAX96717_DEFAULT_CLKOUT_RATE, 0);\n-\tif (ret < 0)\n-\t\tgoto free_init_name;\n-\n-\tret = devm_clk_hw_register(dev, &priv->clk_hw);\n-\tkfree(init.name);\n-\tif (ret)\n-\t\treturn dev_err_probe(dev, ret, \"Cannot register clock HW\\n\");\n-\n-\tret = devm_of_clk_add_hw_provider(dev, of_clk_hw_simple_get,\n-\t\t\t\t\t &priv->clk_hw);\n-\tif (ret)\n-\t\treturn dev_err_probe(dev, ret,\n-\t\t\t\t \"Cannot add OF clock provider\\n\");\n-\n-\treturn 0;\n-\n-free_init_name:\n-\tkfree(init.name);\n-\treturn ret;\n-}\n-\n-static int max96717_init_csi_lanes(struct max96717_priv *priv)\n-{\n-\tstruct v4l2_mbus_config_mipi_csi2 *mipi = &priv->mipi_csi2;\n-\tunsigned long lanes_used = 0;\n-\tunsigned int nlanes, lane, val = 0;\n-\tint ret;\n-\n-\tnlanes = mipi->num_data_lanes;\n-\n-\tret = cci_update_bits(priv->regmap, MAX96717_MIPI_RX1,\n-\t\t\t MAX96717_MIPI_LANES_CNT,\n-\t\t\t FIELD_PREP(MAX96717_MIPI_LANES_CNT,\n-\t\t\t\t\t nlanes - 1), NULL);\n-\n-\t/* lanes polarity */\n-\tfor (lane = 0; lane < nlanes + 1; lane++) {\n-\t\tif (!mipi->lane_polarities[lane])\n-\t\t\tcontinue;\n-\t\t/* Clock lane */\n-\t\tif (lane == 0)\n-\t\t\tval |= BIT(2);\n-\t\telse if (lane < 3)\n-\t\t\tval |= BIT(lane - 1);\n-\t\telse\n-\t\t\tval |= BIT(lane);\n-\t}\n-\n-\tcci_update_bits(priv->regmap, MAX96717_MIPI_RX5,\n-\t\t\tMAX96717_PHY2_LANES_POL,\n-\t\t\tFIELD_PREP(MAX96717_PHY2_LANES_POL, val), &ret);\n-\n-\tcci_update_bits(priv->regmap, MAX96717_MIPI_RX4,\n-\t\t\tMAX96717_PHY1_LANES_POL,\n-\t\t\tFIELD_PREP(MAX96717_PHY1_LANES_POL,\n-\t\t\t\t val >> 3), &ret);\n-\t/* lanes mapping */\n-\tfor (lane = 0, val = 0; lane < nlanes; 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 < MAX96717_CSI_NLANES; lane++) {\n-\t\tunsigned int idx = find_first_zero_bit(&lanes_used,\n-\t\t\t\t\t\t MAX96717_CSI_NLANES);\n-\n-\t\tval |= idx << (lane * 2);\n-\t\tlanes_used |= BIT(idx);\n-\t}\n-\n-\tcci_update_bits(priv->regmap, MAX96717_MIPI_RX3,\n-\t\t\tMAX96717_PHY1_LANES_MAP,\n-\t\t\tFIELD_PREP(MAX96717_PHY1_LANES_MAP, val), &ret);\n-\n-\treturn cci_update_bits(priv->regmap, MAX96717_MIPI_RX2,\n-\t\t\t MAX96717_PHY2_LANES_MAP,\n-\t\t\t FIELD_PREP(MAX96717_PHY2_LANES_MAP, val >> 4),\n-\t\t\t &ret);\n-}\n-\n-static int max96717_hw_init(struct max96717_priv *priv)\n-{\n-\tstruct device *dev = &priv->client->dev;\n-\tu64 dev_id, val;\n-\tint ret;\n-\n-\tret = cci_read(priv->regmap, MAX96717_DEV_ID, &dev_id, NULL);\n-\tif (ret)\n-\t\treturn dev_err_probe(dev, ret,\n-\t\t\t\t \"Fail to read the device id\\n\");\n-\n-\tif (dev_id != MAX96717_DEVICE_ID && dev_id != MAX96717F_DEVICE_ID)\n-\t\treturn dev_err_probe(dev, -EOPNOTSUPP,\n-\t\t\t\t \"Unsupported device id got %x\\n\", (u8)dev_id);\n-\n-\tret = cci_read(priv->regmap, MAX96717_DEV_REV, &val, NULL);\n-\tif (ret)\n-\t\treturn dev_err_probe(dev, ret,\n-\t\t\t\t \"Fail to read device revision\");\n-\n-\tdev_dbg(dev, \"Found %x (rev %lx)\\n\", (u8)dev_id,\n-\t\t(u8)val & MAX96717_DEV_REV_MASK);\n-\n-\tret = cci_read(priv->regmap, MAX96717_MIPI_RX_EXT11, &val, NULL);\n-\tif (ret)\n-\t\treturn dev_err_probe(dev, ret,\n-\t\t\t\t \"Fail to read mipi rx extension\");\n-\n-\tif (!(val & MAX96717_TUN_MODE))\n-\t\treturn dev_err_probe(dev, -EOPNOTSUPP,\n-\t\t\t\t \"Only supporting tunnel mode\");\n-\n-\treturn max96717_init_csi_lanes(priv);\n-}\n-\n-static int max96717_parse_dt(struct max96717_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-\tunsigned char 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 MAX96717_PAD_SINK, 0, 0);\n-\tif (!ep_fwnode)\n-\t\treturn dev_err_probe(dev, -ENOENT, \"no endpoint found\\n\");\n-\n-\tret = v4l2_fwnode_endpoint_parse(ep_fwnode, &vep);\n-\n-\tfwnode_handle_put(ep_fwnode);\n-\n-\tif (ret < 0)\n-\t\treturn dev_err_probe(dev, ret, \"Failed to parse sink endpoint\");\n-\n-\tnum_data_lanes = vep.bus.mipi_csi2.num_data_lanes;\n-\tif (num_data_lanes < 1 || num_data_lanes > MAX96717_CSI_NLANES)\n-\t\treturn dev_err_probe(dev, -EINVAL,\n-\t\t\t\t \"Invalid data lanes must be 1 to 4\\n\");\n-\n-\tpriv->mipi_csi2 = vep.bus.mipi_csi2;\n-\n-\treturn 0;\n-}\n-\n-static int max96717_probe(struct i2c_client *client)\n-{\n-\tstruct device *dev = &client->dev;\n-\tstruct max96717_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-\tpriv->regmap = devm_cci_regmap_init_i2c(client, 16);\n-\tif (IS_ERR(priv->regmap)) {\n-\t\tret = PTR_ERR(priv->regmap);\n-\t\treturn dev_err_probe(dev, ret, \"Failed to init regmap\\n\");\n-\t}\n-\n-\tret = max96717_parse_dt(priv);\n-\tif (ret)\n-\t\treturn dev_err_probe(dev, ret, \"Failed to parse the dt\\n\");\n-\n-\tret = max96717_hw_init(priv);\n-\tif (ret)\n-\t\treturn dev_err_probe(dev, ret,\n-\t\t\t\t \"Failed to initialize the hardware\\n\");\n-\n-\tret = max96717_gpiochip_probe(priv);\n-\tif (ret)\n-\t\treturn dev_err_probe(&client->dev, ret,\n-\t\t\t\t \"Failed to init gpiochip\\n\");\n-\n-\tret = max96717_register_clkout(priv);\n-\tif (ret)\n-\t\treturn dev_err_probe(dev, ret, \"Failed to register clkout\\n\");\n-\n-\tret = max96717_subdev_init(priv);\n-\tif (ret)\n-\t\treturn dev_err_probe(dev, ret,\n-\t\t\t\t \"Failed to initialize v4l2 subdev\\n\");\n-\n-\tret = max96717_i2c_mux_init(priv);\n-\tif (ret) {\n-\t\tdev_err_probe(dev, ret, \"failed to add remote i2c adapter\\n\");\n-\t\tmax96717_subdev_uninit(priv);\n-\t}\n-\n-\treturn ret;\n-}\n-\n-static void max96717_remove(struct i2c_client *client)\n-{\n-\tstruct v4l2_subdev *sd = i2c_get_clientdata(client);\n-\tstruct max96717_priv *priv = sd_to_max96717(sd);\n-\n-\tmax96717_subdev_uninit(priv);\n-\ti2c_mux_del_adapters(priv->mux);\n-}\n-\n-static const struct of_device_id max96717_of_ids[] = {\n-\t{ .compatible = \"maxim,max96717f\" },\n-\t{ }\n-};\n-MODULE_DEVICE_TABLE(of, max96717_of_ids);\n-\n-static struct i2c_driver max96717_i2c_driver = {\n-\t.driver\t= {\n-\t\t.name\t\t= \"max96717\",\n-\t\t.of_match_table\t= max96717_of_ids,\n-\t},\n-\t.probe\t\t= max96717_probe,\n-\t.remove\t\t= max96717_remove,\n-};\n-\n-module_i2c_driver(max96717_i2c_driver);\n-\n-MODULE_DESCRIPTION(\"Maxim GMSL2 MAX96717 Serializer Driver\");\n-MODULE_AUTHOR(\"Julien Massot <julien.massot@collabora.com>\");\n-MODULE_LICENSE(\"GPL\");\n", "prefixes": [ "v10", "21/22" ] }