From patchwork Mon Mar 3 16:02:05 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jai Luthra X-Patchwork-Id: 870021 Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 2455A214A9E; Mon, 3 Mar 2025 16:02:25 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=213.167.242.64 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741017747; cv=none; b=GoasHtD3zfjOcb0p9pmjBBzYp3JS8jT9zb73Mi8q2eZcqEX5GottAG966KhPyX4ndG5k3m+ODy2sbQHSyVVT0rXQ9FzAsSpTe3HAXGWeYHgKt1hr/brp/DiXCCsfVIjJoa/cQEPTMeYMeEKzhz99JPTEwAeOUSz+NfxLf4iM+lc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741017747; c=relaxed/simple; bh=JLH9MJR6Zq6nZAb3s9lKLinR8MoPluF9Iq/DKAfHIFU=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=qR5xrvhrge51lMo7Uz2ha4cMBzpX96iUZbYfJ1uiYEEvCpQXHhstrdsJYXnr7AUBHtuBWulPCKh1tBhY7KVqAXwlEC9gAHcEYO63zMZrI8m+81Di2hdL8ZXMs2JVCbEJtj8h4Tw17ISWwHRvfOtNEr4yRkm6NYoHwbInSUQ5myI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=ideasonboard.com; spf=pass smtp.mailfrom=ideasonboard.com; dkim=pass (1024-bit key) header.d=ideasonboard.com header.i=@ideasonboard.com header.b=SgTtv68T; arc=none smtp.client-ip=213.167.242.64 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=ideasonboard.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=ideasonboard.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="SgTtv68T" Received: from mail.ideasonboard.com (unknown [IPv6:2401:4900:1c69:8872:6fe4:6987:313:70cc]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 141341189; Mon, 3 Mar 2025 17:00:52 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1741017653; bh=JLH9MJR6Zq6nZAb3s9lKLinR8MoPluF9Iq/DKAfHIFU=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=SgTtv68TVcBtayrUxnS/TRFIVaGcKyCkrQi2DmTo0bJr5tc7gVXyEwfJEoQ7ywokt 7gdUUyapNT9IpOyzmqIB/mGITOedYphtA23oU23OSITgGYf4WSzxTf+DMn39DH/LgZ jAtE5oJMzknNLZU3Uo2wSacwV19SfRxUNXiK7JfY= From: Jai Luthra Date: Mon, 03 Mar 2025 21:32:05 +0530 Subject: [PATCH v3 02/19] media: i2c: ds90ub913: Fix returned fmt from .set_fmt() Precedence: bulk X-Mailing-List: linux-media@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20250303-b4-ub9xx-err-handling-v3-2-7d178796a2b9@ideasonboard.com> References: <20250303-b4-ub9xx-err-handling-v3-0-7d178796a2b9@ideasonboard.com> In-Reply-To: <20250303-b4-ub9xx-err-handling-v3-0-7d178796a2b9@ideasonboard.com> To: Mauro Carvalho Chehab , Sakari Ailus Cc: Tomi Valkeinen , Devarsh Thakkar , linux-media@vger.kernel.org, linux-kernel@vger.kernel.org, stable@vger.kernel.org, Jai Luthra X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=1009; i=jai.luthra@ideasonboard.com; h=from:subject:message-id; bh=GzgsmXWOYQnJFZCCQStgSFGp+y0aPfeevNKeKV6gVVM=; b=owEBbQKS/ZANAwAIAUPekfkkmnFFAcsmYgBnxdJ+CVnm+xnkIRMaDDVGjWw0y8LZ/z5xqRq90 96wRnQd8Y+JAjMEAAEIAB0WIQRN4NgY5dV16NRar8VD3pH5JJpxRQUCZ8XSfgAKCRBD3pH5JJpx RTpQD/9ralZV2/880aAJ1glGh8LZagW7GbVtR3bxrmTUyGx/PG/vfhnYFV4TsLHmU1OooMvpCmc 7b8UAM35cmEDz4aSrx78UjZSzmZhOSU5r9cmLcp4x40k2zTX4ikjdF0lt+101znyKVWF/Af6lRh HjbeD6pwfRQBuTKJE+OvQvAKPv/rXTfmRnKRJM0KirCKE71OLOYusz4IQQxTkmwPWVFQEXmq1IT A69aU0S2a8kyj3RyquueAbM6xevF2FtLsSeoS2uQ5HIUedVzX9WqplRSOzQvjpLOnlvq5BeZZQU 9y94DLgPRri4NZN5kIaHOwSSyAFd9/pkbZsFIN90iciZhLZPPTgreo/RChuMHJseXi98lCmEr1W LxNbq1QeJAdQHbcyNUW0pOnWpttGMDw4IocTiwdtqevffBA0nKJQVDQGLxLF5tUNVroImbTfBLC iXxsL9j6PwT9ECFej3Pam8aL/N88mAF4ZsSmqZDVZKbYuwzrnRYMXBaiftVEHPHhAjPHkYJkSZt vap/dQ8oqAe4fu2BSD+H9ARScYbn3dIoGt0DhWUtBNRuYFn/GIjyWC2fDKD/WglE4UancpDriBb LS9Vtf37MYqj6LktW1Z9TETNHK65RfRvznlt6q7JKV9S0tOxb/HfeNS97TjZiMKczgNOd22YW65 dZv5VgKDI1pW0kw== X-Developer-Key: i=jai.luthra@ideasonboard.com; a=openpgp; fpr=4DE0D818E5D575E8D45AAFC543DE91F9249A7145 From: Tomi Valkeinen When setting the sink pad's stream format, set_fmt accidentally changes the returned format's code to 'outcode', while the purpose is to only use the 'outcode' for the propagated source stream format. Fixes: c158d0d4ff15 ("media: i2c: add DS90UB913 driver") Cc: stable@vger.kernel.org Signed-off-by: Tomi Valkeinen Signed-off-by: Jai Luthra --- drivers/media/i2c/ds90ub913.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/media/i2c/ds90ub913.c b/drivers/media/i2c/ds90ub913.c index fd2d2d5272bfb688f00d7bf5a109e978f6c322e6..1445ebbcc9cabb3ab43a670aa165deea52db5f35 100644 --- a/drivers/media/i2c/ds90ub913.c +++ b/drivers/media/i2c/ds90ub913.c @@ -450,10 +450,10 @@ static int ub913_set_fmt(struct v4l2_subdev *sd, if (!fmt) return -EINVAL; - format->format.code = finfo->outcode; - *fmt = format->format; + fmt->code = finfo->outcode; + return 0; } From patchwork Mon Mar 3 16:02:07 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jai Luthra X-Patchwork-Id: 870020 Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C991C218AA5; Mon, 3 Mar 2025 16:02:38 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=213.167.242.64 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741017762; cv=none; b=gfeIN5frUhbcsmCz+TprwdAkfPDpXavsuXOwTq7BxskRU+iHkRCoiLtLSERb/Au+asZuzF4Pi6C0J/49nO+nQR17nhRGqUv3Qg7Ny4IU89LvCExFyVZtvd+WIxcIXF7rfV9y7iC9bTSvJmDSG9lXKUScusI8bgJjShyAm/HJVls= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741017762; c=relaxed/simple; bh=L2eaW6/kuQzzNKHthgmp5q53rQNb7ZOZcOYv9gBsNSg=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=C7dFH439W18g5ap7wYRLAayK5Lgn/g9okdVzkRaJXrU1nd7EpmNT+1EEcZu5KnvoBAQEVVhMFVExmkwzusMXPpVygH7FAoJTHdkBznqdRJphkZY/dQRmFtuEo3r3uqb+Izap4f886ZQc2xJ30kd4ff3SO8LkGeKOpdR8OJJQsas= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=ideasonboard.com; spf=pass smtp.mailfrom=ideasonboard.com; dkim=pass (1024-bit key) header.d=ideasonboard.com header.i=@ideasonboard.com header.b=wKvE30fh; arc=none smtp.client-ip=213.167.242.64 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=ideasonboard.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=ideasonboard.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="wKvE30fh" Received: from mail.ideasonboard.com (unknown [IPv6:2401:4900:1c69:8872:6fe4:6987:313:70cc]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 9BAF41189; Mon, 3 Mar 2025 17:01:05 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1741017666; bh=L2eaW6/kuQzzNKHthgmp5q53rQNb7ZOZcOYv9gBsNSg=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=wKvE30fhh829hrACDe3gjmr+t1ulAk9lkJqtuS7E7FsypRQTyG4FfMPFriZ/Jnonx EYaZ5F4oD9wN4ckCLu5WUR/5vj9o/SC4PEFthur+AsJw9RPVUH0qpKASnG65gdCxNe 1CUx9azDYFq+8r8tTjxr6Cyd9hG0IbNTItpXnMkE= From: Jai Luthra Date: Mon, 03 Mar 2025 21:32:07 +0530 Subject: [PATCH v3 04/19] media: i2c: ds90ub9xx: Add err parameter to read/write funcs Precedence: bulk X-Mailing-List: linux-media@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20250303-b4-ub9xx-err-handling-v3-4-7d178796a2b9@ideasonboard.com> References: <20250303-b4-ub9xx-err-handling-v3-0-7d178796a2b9@ideasonboard.com> In-Reply-To: <20250303-b4-ub9xx-err-handling-v3-0-7d178796a2b9@ideasonboard.com> To: Mauro Carvalho Chehab , Sakari Ailus Cc: Tomi Valkeinen , Devarsh Thakkar , linux-media@vger.kernel.org, linux-kernel@vger.kernel.org, stable@vger.kernel.org, Jai Luthra X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=55814; i=jai.luthra@ideasonboard.com; h=from:subject:message-id; bh=15RccD1KjOv1/+7/zNR7rRgNQTubVcznT6sepqdSa2Q=; b=owEBbQKS/ZANAwAIAUPekfkkmnFFAcsmYgBnxdJ+TQTb4jrcqExyG3a5wjfJM9gIEPR+cjof/ M+FGqnLz8CJAjMEAAEIAB0WIQRN4NgY5dV16NRar8VD3pH5JJpxRQUCZ8XSfgAKCRBD3pH5JJpx RRrwD/4vmSaBQ3ysUeRBWAO8udsrMyNK5bKxvip/p94HseGqjUt0OuiqFpZ6vLdMBDxYF8+YXiI x3YA1w5WDrXIJC8an4jnXK2TJ6yzlbvGYqQOoT/QWSm6GzANHug2oIGJhLYs0d9Q03X1us8PiRO uQ2Ab4Tc5fjXkozjgvwAS4ApJf2jiGyYpZV9tfxDdxCJS1Z6pP2MqlujXmgKZi6P5GV6KFQpRtI cH0tBGxZry78xQVtRaPl5Dp4VUVxT9TrU17SddcKWmcUoCQDk0dvPd8hbhCUmsH4rQSNss3Paao hsh+ge0VSZfuGmMiH/pw+r563N8EddZEYotZ+rHfU9X722wq3J9KufuBnx0eWnpr/NS2K2aFJu1 Vqoa9npM0Bu9ZEmQ+b696BP89rpweGBgef/xjr8rSXse++Av8/VFzq25A6lqattlRCqiKPCS15S jTJiwCKcp44l+oGYyzrDmAqe/TeSoDw++v8rhGBXaqNo2WhrdQH6Yv/M/Ao1LsDWpkNYvdXtaix hoBC4oq51CmQxPm9ydAY2/AlL8pPV/gYZavOwyK25ELrrLEh9HghhmrshQQeKZ+zVhZ97EEButN yIL8/nSB0hvTf64U1qnJGcQNc3GdlUPpP8KR+VJ3ph2BvHeP4E5Hi8gWEXGDv/U0suCZhI8nh6t 60WScdnxuUn+Ong== X-Developer-Key: i=jai.luthra@ideasonboard.com; a=openpgp; fpr=4DE0D818E5D575E8D45AAFC543DE91F9249A7145 From: Tomi Valkeinen To make future error handling in the drivers easier, add "int *err" parameter to all the i2c register access functions. It functions the same was as with e.g. CCI reg write/read helpers. This was accomplished with the following semantic patch: @@ identifier FUNC =~ "^ub9.._(rxport_|txport_|ind_)?(read|write|update_bits)(16|_ind)?$"; @@ FUNC(... + , int *err ) { ... int ret; + + if (err && *err) + return *err; ... + if (ret && err) + *err = ret; + return ret; } @@ identifier FUNC =~ "^ub9.._(rxport_|txport_|ind_)?(read|write|update_bits)(16|_ind)?$"; @@ FUNC(... + , NULL ) Signed-off-by: Tomi Valkeinen Signed-off-by: Jai Luthra --- drivers/media/i2c/ds90ub913.c | 52 +++-- drivers/media/i2c/ds90ub953.c | 94 +++++---- drivers/media/i2c/ds90ub960.c | 441 ++++++++++++++++++++++++++++-------------- 3 files changed, 390 insertions(+), 197 deletions(-) diff --git a/drivers/media/i2c/ds90ub913.c b/drivers/media/i2c/ds90ub913.c index facbee79164eec1fbccaea2c1d4d62cf439e49b6..f38421d34d204fa9ab898d10c6b69942858bced2 100644 --- a/drivers/media/i2c/ds90ub913.c +++ b/drivers/media/i2c/ds90ub913.c @@ -119,11 +119,15 @@ static const struct ub913_format_info *ub913_find_format(u32 incode) return NULL; } -static int ub913_read(const struct ub913_data *priv, u8 reg, u8 *val) +static int ub913_read(const struct ub913_data *priv, u8 reg, u8 *val, + int *err) { unsigned int v; int ret; + if (err && *err) + return *err; + ret = regmap_read(priv->regmap, reg, &v); if (ret) { dev_err(&priv->client->dev, @@ -134,31 +138,47 @@ static int ub913_read(const struct ub913_data *priv, u8 reg, u8 *val) *val = v; out: + if (ret && err) + *err = ret; + return ret; } -static int ub913_write(const struct ub913_data *priv, u8 reg, u8 val) +static int ub913_write(const struct ub913_data *priv, u8 reg, u8 val, + int *err) { int ret; + if (err && *err) + return *err; + ret = regmap_write(priv->regmap, reg, val); if (ret < 0) dev_err(&priv->client->dev, "Cannot write register 0x%02x: %d!\n", reg, ret); + if (ret && err) + *err = ret; + return ret; } static int ub913_update_bits(const struct ub913_data *priv, u8 reg, u8 mask, - u8 val) + u8 val, int *err) { int ret; + if (err && *err) + return *err; + ret = regmap_update_bits(priv->regmap, reg, mask, val); if (ret < 0) dev_err(&priv->client->dev, "Cannot update register 0x%02x %d!\n", reg, ret); + if (ret && err) + *err = ret; + return ret; } @@ -206,7 +226,7 @@ static int ub913_gpiochip_probe(struct ub913_data *priv) int ret; /* Initialize GPIOs 0 and 1 to local control, tri-state */ - ub913_write(priv, UB913_REG_GPIO_CFG(0), 0); + ub913_write(priv, UB913_REG_GPIO_CFG(0), 0, NULL); gc->label = dev_name(dev); gc->parent = dev; @@ -486,23 +506,23 @@ static int ub913_log_status(struct v4l2_subdev *sd) struct device *dev = &priv->client->dev; u8 v = 0, v1 = 0, v2 = 0; - ub913_read(priv, UB913_REG_MODE_SEL, &v); + ub913_read(priv, UB913_REG_MODE_SEL, &v, NULL); dev_info(dev, "MODE_SEL %#02x\n", v); - ub913_read(priv, UB913_REG_CRC_ERRORS_LSB, &v1); - ub913_read(priv, UB913_REG_CRC_ERRORS_MSB, &v2); + ub913_read(priv, UB913_REG_CRC_ERRORS_LSB, &v1, NULL); + ub913_read(priv, UB913_REG_CRC_ERRORS_MSB, &v2, NULL); dev_info(dev, "CRC errors %u\n", v1 | (v2 << 8)); /* clear CRC errors */ - ub913_read(priv, UB913_REG_GENERAL_CFG, &v); + ub913_read(priv, UB913_REG_GENERAL_CFG, &v, NULL); ub913_write(priv, UB913_REG_GENERAL_CFG, - v | UB913_REG_GENERAL_CFG_CRC_ERR_RESET); - ub913_write(priv, UB913_REG_GENERAL_CFG, v); + v | UB913_REG_GENERAL_CFG_CRC_ERR_RESET, NULL); + ub913_write(priv, UB913_REG_GENERAL_CFG, v, NULL); - ub913_read(priv, UB913_REG_GENERAL_STATUS, &v); + ub913_read(priv, UB913_REG_GENERAL_STATUS, &v, NULL); dev_info(dev, "GENERAL_STATUS %#02x\n", v); - ub913_read(priv, UB913_REG_PLL_OVR, &v); + ub913_read(priv, UB913_REG_PLL_OVR, &v, NULL); dev_info(dev, "PLL_OVR %#02x\n", v); return 0; @@ -658,11 +678,11 @@ static int ub913_i2c_master_init(struct ub913_data *priv) scl_high = div64_u64((u64)scl_high * ref, 1000000000); scl_low = div64_u64((u64)scl_low * ref, 1000000000); - ret = ub913_write(priv, UB913_REG_SCL_HIGH_TIME, scl_high); + ret = ub913_write(priv, UB913_REG_SCL_HIGH_TIME, scl_high, NULL); if (ret) return ret; - ret = ub913_write(priv, UB913_REG_SCL_LOW_TIME, scl_low); + ret = ub913_write(priv, UB913_REG_SCL_LOW_TIME, scl_low, NULL); if (ret) return ret; @@ -731,7 +751,7 @@ static int ub913_hw_init(struct ub913_data *priv) int ret; u8 v; - ret = ub913_read(priv, UB913_REG_MODE_SEL, &v); + ret = ub913_read(priv, UB913_REG_MODE_SEL, &v, NULL); if (ret) return ret; @@ -752,7 +772,7 @@ static int ub913_hw_init(struct ub913_data *priv) ret = ub913_update_bits(priv, UB913_REG_GENERAL_CFG, UB913_REG_GENERAL_CFG_PCLK_RISING, FIELD_PREP(UB913_REG_GENERAL_CFG_PCLK_RISING, - priv->pclk_polarity_rising)); + priv->pclk_polarity_rising), NULL); if (ret) return ret; diff --git a/drivers/media/i2c/ds90ub953.c b/drivers/media/i2c/ds90ub953.c index 7b33b8cc83c17fce7d3ce6bf73c2ec8bc13a0bfd..fbd977760c6b1ccdec90b90bced4dc29932f3893 100644 --- a/drivers/media/i2c/ds90ub953.c +++ b/drivers/media/i2c/ds90ub953.c @@ -185,11 +185,14 @@ static inline struct ub953_data *sd_to_ub953(struct v4l2_subdev *sd) * HW Access */ -static int ub953_read(struct ub953_data *priv, u8 reg, u8 *val) +static int ub953_read(struct ub953_data *priv, u8 reg, u8 *val, int *err) { unsigned int v; int ret; + if (err && *err) + return *err; + mutex_lock(&priv->reg_lock); ret = regmap_read(priv->regmap, reg, &v); @@ -204,13 +207,19 @@ static int ub953_read(struct ub953_data *priv, u8 reg, u8 *val) out_unlock: mutex_unlock(&priv->reg_lock); + if (ret && err) + *err = ret; + return ret; } -static int ub953_write(struct ub953_data *priv, u8 reg, u8 val) +static int ub953_write(struct ub953_data *priv, u8 reg, u8 val, int *err) { int ret; + if (err && *err) + return *err; + mutex_lock(&priv->reg_lock); ret = regmap_write(priv->regmap, reg, val); @@ -220,6 +229,9 @@ static int ub953_write(struct ub953_data *priv, u8 reg, u8 val) mutex_unlock(&priv->reg_lock); + if (ret && err) + *err = ret; + return ret; } @@ -244,11 +256,15 @@ static int ub953_select_ind_reg_block(struct ub953_data *priv, u8 block) } __maybe_unused -static int ub953_read_ind(struct ub953_data *priv, u8 block, u8 reg, u8 *val) +static int ub953_read_ind(struct ub953_data *priv, u8 block, u8 reg, u8 *val, + int *err) { unsigned int v; int ret; + if (err && *err) + return *err; + mutex_lock(&priv->reg_lock); ret = ub953_select_ind_reg_block(priv, block); @@ -276,14 +292,21 @@ static int ub953_read_ind(struct ub953_data *priv, u8 block, u8 reg, u8 *val) out_unlock: mutex_unlock(&priv->reg_lock); + if (ret && err) + *err = ret; + return ret; } __maybe_unused -static int ub953_write_ind(struct ub953_data *priv, u8 block, u8 reg, u8 val) +static int ub953_write_ind(struct ub953_data *priv, u8 block, u8 reg, u8 val, + int *err) { int ret; + if (err && *err) + return *err; + mutex_lock(&priv->reg_lock); ret = ub953_select_ind_reg_block(priv, block); @@ -308,6 +331,9 @@ static int ub953_write_ind(struct ub953_data *priv, u8 block, u8 reg, u8 val) out_unlock: mutex_unlock(&priv->reg_lock); + if (ret && err) + *err = ret; + return ret; } @@ -320,7 +346,7 @@ static int ub953_gpio_get_direction(struct gpio_chip *gc, unsigned int offset) int ret; u8 v; - ret = ub953_read(priv, UB953_REG_GPIO_INPUT_CTRL, &v); + ret = ub953_read(priv, UB953_REG_GPIO_INPUT_CTRL, &v, NULL); if (ret) return ret; @@ -366,7 +392,7 @@ static int ub953_gpio_get(struct gpio_chip *gc, unsigned int offset) int ret; u8 v; - ret = ub953_read(priv, UB953_REG_GPIO_PIN_STS, &v); + ret = ub953_read(priv, UB953_REG_GPIO_PIN_STS, &v, NULL); if (ret) return ret; @@ -400,11 +426,11 @@ static int ub953_gpiochip_probe(struct ub953_data *priv) int ret; /* Set all GPIOs to local input mode */ - ret = ub953_write(priv, UB953_REG_LOCAL_GPIO_DATA, 0); + ret = ub953_write(priv, UB953_REG_LOCAL_GPIO_DATA, 0, NULL); if (ret) return ret; - ret = ub953_write(priv, UB953_REG_GPIO_INPUT_CTRL, 0xf); + ret = ub953_write(priv, UB953_REG_GPIO_INPUT_CTRL, 0xf, NULL); if (ret) return ret; @@ -615,15 +641,15 @@ static int ub953_log_status(struct v4l2_subdev *sd) u8 gpio_pin_sts = 0; for (i = 0; i < sizeof(id); i++) - ub953_read(priv, UB953_REG_FPD3_RX_ID(i), &id[i]); + ub953_read(priv, UB953_REG_FPD3_RX_ID(i), &id[i], NULL); dev_info(dev, "ID '%.*s'\n", (int)sizeof(id), id); - ub953_read(priv, UB953_REG_GENERAL_STATUS, &v); + ub953_read(priv, UB953_REG_GENERAL_STATUS, &v, NULL); dev_info(dev, "GENERAL_STATUS %#02x\n", v); - ub953_read(priv, UB953_REG_CRC_ERR_CNT1, &v1); - ub953_read(priv, UB953_REG_CRC_ERR_CNT2, &v2); + ub953_read(priv, UB953_REG_CRC_ERR_CNT1, &v1, NULL); + ub953_read(priv, UB953_REG_CRC_ERR_CNT2, &v2, NULL); dev_info(dev, "CRC error count %u\n", v1 | (v2 << 8)); /* Clear CRC error counter */ @@ -632,34 +658,34 @@ static int ub953_log_status(struct v4l2_subdev *sd) UB953_REG_BC_CTRL_CRC_ERR_CLR, UB953_REG_BC_CTRL_CRC_ERR_CLR); - ub953_read(priv, UB953_REG_CSI_ERR_CNT, &v); + ub953_read(priv, UB953_REG_CSI_ERR_CNT, &v, NULL); dev_info(dev, "CSI error count %u\n", v); - ub953_read(priv, UB953_REG_CSI_ERR_STATUS, &v); + ub953_read(priv, UB953_REG_CSI_ERR_STATUS, &v, NULL); dev_info(dev, "CSI_ERR_STATUS %#02x\n", v); - ub953_read(priv, UB953_REG_CSI_ERR_DLANE01, &v); + ub953_read(priv, UB953_REG_CSI_ERR_DLANE01, &v, NULL); dev_info(dev, "CSI_ERR_DLANE01 %#02x\n", v); - ub953_read(priv, UB953_REG_CSI_ERR_DLANE23, &v); + ub953_read(priv, UB953_REG_CSI_ERR_DLANE23, &v, NULL); dev_info(dev, "CSI_ERR_DLANE23 %#02x\n", v); - ub953_read(priv, UB953_REG_CSI_ERR_CLK_LANE, &v); + ub953_read(priv, UB953_REG_CSI_ERR_CLK_LANE, &v, NULL); dev_info(dev, "CSI_ERR_CLK_LANE %#02x\n", v); - ub953_read(priv, UB953_REG_CSI_PKT_HDR_VC_ID, &v); + ub953_read(priv, UB953_REG_CSI_PKT_HDR_VC_ID, &v, NULL); dev_info(dev, "CSI packet header VC %u ID %u\n", v >> 6, v & 0x3f); - ub953_read(priv, UB953_REG_PKT_HDR_WC_LSB, &v1); - ub953_read(priv, UB953_REG_PKT_HDR_WC_MSB, &v2); + ub953_read(priv, UB953_REG_PKT_HDR_WC_LSB, &v1, NULL); + ub953_read(priv, UB953_REG_PKT_HDR_WC_MSB, &v2, NULL); dev_info(dev, "CSI packet header WC %u\n", (v2 << 8) | v1); - ub953_read(priv, UB953_REG_CSI_ECC, &v); + ub953_read(priv, UB953_REG_CSI_ECC, &v, NULL); dev_info(dev, "CSI ECC %#02x\n", v); - ub953_read(priv, UB953_REG_LOCAL_GPIO_DATA, &gpio_local_data); - ub953_read(priv, UB953_REG_GPIO_INPUT_CTRL, &gpio_input_ctrl); - ub953_read(priv, UB953_REG_GPIO_PIN_STS, &gpio_pin_sts); + ub953_read(priv, UB953_REG_LOCAL_GPIO_DATA, &gpio_local_data, NULL); + ub953_read(priv, UB953_REG_GPIO_INPUT_CTRL, &gpio_input_ctrl, NULL); + ub953_read(priv, UB953_REG_GPIO_PIN_STS, &gpio_pin_sts, NULL); for (i = 0; i < UB953_NUM_GPIOS; i++) { dev_info(dev, @@ -843,11 +869,11 @@ static int ub953_i2c_master_init(struct ub953_data *priv) scl_high = div64_u64((u64)scl_high * ref, 1000000000) - 5; scl_low = div64_u64((u64)scl_low * ref, 1000000000) - 5; - ret = ub953_write(priv, UB953_REG_SCL_HIGH_TIME, scl_high); + ret = ub953_write(priv, UB953_REG_SCL_HIGH_TIME, scl_high, NULL); if (ret) return ret; - ret = ub953_write(priv, UB953_REG_SCL_LOW_TIME, scl_low); + ret = ub953_write(priv, UB953_REG_SCL_LOW_TIME, scl_low, NULL); if (ret) return ret; @@ -986,11 +1012,11 @@ static int ub953_write_clkout_regs(struct ub953_data *priv, clkout_ctrl1 = clkout_data->n; - ret = ub953_write(priv, UB953_REG_CLKOUT_CTRL0, clkout_ctrl0); + ret = ub953_write(priv, UB953_REG_CLKOUT_CTRL0, clkout_ctrl0, NULL); if (ret) return ret; - ret = ub953_write(priv, UB953_REG_CLKOUT_CTRL1, clkout_ctrl1); + ret = ub953_write(priv, UB953_REG_CLKOUT_CTRL1, clkout_ctrl1, NULL); if (ret) return ret; @@ -1009,13 +1035,13 @@ static unsigned long ub953_clkout_recalc_rate(struct clk_hw *hw, u64 rate; int ret; - ret = ub953_read(priv, UB953_REG_CLKOUT_CTRL0, &ctrl0); + ret = ub953_read(priv, UB953_REG_CLKOUT_CTRL0, &ctrl0, NULL); if (ret) { dev_err(dev, "Failed to read CLKOUT_CTRL0: %d\n", ret); return 0; } - ret = ub953_read(priv, UB953_REG_CLKOUT_CTRL1, &ctrl1); + ret = ub953_read(priv, UB953_REG_CLKOUT_CTRL1, &ctrl1, NULL); if (ret) { dev_err(dev, "Failed to read CLKOUT_CTRL1: %d\n", ret); return 0; @@ -1191,7 +1217,7 @@ static int ub953_hw_init(struct ub953_data *priv) int ret; u8 v; - ret = ub953_read(priv, UB953_REG_MODE_SEL, &v); + ret = ub953_read(priv, UB953_REG_MODE_SEL, &v, NULL); if (ret) return ret; @@ -1231,13 +1257,13 @@ static int ub953_hw_init(struct ub953_data *priv) return dev_err_probe(dev, -EINVAL, "clkin required for non-sync ext mode\n"); - ret = ub953_read(priv, UB953_REG_REV_MASK_ID, &v); + ret = ub953_read(priv, UB953_REG_REV_MASK_ID, &v, NULL); if (ret) return dev_err_probe(dev, ret, "Failed to read revision"); dev_info(dev, "Found %s rev/mask %#04x\n", priv->hw_data->model, v); - ret = ub953_read(priv, UB953_REG_GENERAL_CFG, &v); + ret = ub953_read(priv, UB953_REG_GENERAL_CFG, &v, NULL); if (ret) return ret; @@ -1254,7 +1280,7 @@ static int ub953_hw_init(struct ub953_data *priv) UB953_REG_GENERAL_CFG_CSI_LANE_SEL_SHIFT; v |= UB953_REG_GENERAL_CFG_CRC_TX_GEN_ENABLE; - ret = ub953_write(priv, UB953_REG_GENERAL_CFG, v); + ret = ub953_write(priv, UB953_REG_GENERAL_CFG, v, NULL); if (ret) return ret; diff --git a/drivers/media/i2c/ds90ub960.c b/drivers/media/i2c/ds90ub960.c index 5dde8452739b64dd5b847a7bc1dac556ea43ca6c..09e6d820edc193f4db9c0ebf02bc89b384d75f5b 100644 --- a/drivers/media/i2c/ds90ub960.c +++ b/drivers/media/i2c/ds90ub960.c @@ -618,12 +618,15 @@ static const struct ub960_format_info *ub960_find_format(u32 code) * Basic device access */ -static int ub960_read(struct ub960_data *priv, u8 reg, u8 *val) +static int ub960_read(struct ub960_data *priv, u8 reg, u8 *val, int *err) { struct device *dev = &priv->client->dev; unsigned int v; int ret; + if (err && *err) + return *err; + mutex_lock(&priv->reg_lock); ret = regmap_read(priv->regmap, reg, &v); @@ -638,14 +641,20 @@ static int ub960_read(struct ub960_data *priv, u8 reg, u8 *val) out_unlock: mutex_unlock(&priv->reg_lock); + if (ret && err) + *err = ret; + return ret; } -static int ub960_write(struct ub960_data *priv, u8 reg, u8 val) +static int ub960_write(struct ub960_data *priv, u8 reg, u8 val, int *err) { struct device *dev = &priv->client->dev; int ret; + if (err && *err) + return *err; + mutex_lock(&priv->reg_lock); ret = regmap_write(priv->regmap, reg, val); @@ -655,14 +664,21 @@ static int ub960_write(struct ub960_data *priv, u8 reg, u8 val) mutex_unlock(&priv->reg_lock); + if (ret && err) + *err = ret; + return ret; } -static int ub960_update_bits(struct ub960_data *priv, u8 reg, u8 mask, u8 val) +static int ub960_update_bits(struct ub960_data *priv, u8 reg, u8 mask, u8 val, + int *err) { struct device *dev = &priv->client->dev; int ret; + if (err && *err) + return *err; + mutex_lock(&priv->reg_lock); ret = regmap_update_bits(priv->regmap, reg, mask, val); @@ -672,15 +688,21 @@ static int ub960_update_bits(struct ub960_data *priv, u8 reg, u8 mask, u8 val) mutex_unlock(&priv->reg_lock); + if (ret && err) + *err = ret; + return ret; } -static int ub960_read16(struct ub960_data *priv, u8 reg, u16 *val) +static int ub960_read16(struct ub960_data *priv, u8 reg, u16 *val, int *err) { struct device *dev = &priv->client->dev; __be16 __v; int ret; + if (err && *err) + return *err; + mutex_lock(&priv->reg_lock); ret = regmap_bulk_read(priv->regmap, reg, &__v, sizeof(__v)); @@ -695,6 +717,9 @@ static int ub960_read16(struct ub960_data *priv, u8 reg, u16 *val) out_unlock: mutex_unlock(&priv->reg_lock); + if (ret && err) + *err = ret; + return ret; } @@ -721,12 +746,16 @@ static int ub960_rxport_select(struct ub960_data *priv, u8 nport) return 0; } -static int ub960_rxport_read(struct ub960_data *priv, u8 nport, u8 reg, u8 *val) +static int ub960_rxport_read(struct ub960_data *priv, u8 nport, u8 reg, + u8 *val, int *err) { struct device *dev = &priv->client->dev; unsigned int v; int ret; + if (err && *err) + return *err; + mutex_lock(&priv->reg_lock); ret = ub960_rxport_select(priv, nport); @@ -745,14 +774,21 @@ static int ub960_rxport_read(struct ub960_data *priv, u8 nport, u8 reg, u8 *val) out_unlock: mutex_unlock(&priv->reg_lock); + if (ret && err) + *err = ret; + return ret; } -static int ub960_rxport_write(struct ub960_data *priv, u8 nport, u8 reg, u8 val) +static int ub960_rxport_write(struct ub960_data *priv, u8 nport, u8 reg, + u8 val, int *err) { struct device *dev = &priv->client->dev; int ret; + if (err && *err) + return *err; + mutex_lock(&priv->reg_lock); ret = ub960_rxport_select(priv, nport); @@ -767,15 +803,21 @@ static int ub960_rxport_write(struct ub960_data *priv, u8 nport, u8 reg, u8 val) out_unlock: mutex_unlock(&priv->reg_lock); + if (ret && err) + *err = ret; + return ret; } static int ub960_rxport_update_bits(struct ub960_data *priv, u8 nport, u8 reg, - u8 mask, u8 val) + u8 mask, u8 val, int *err) { struct device *dev = &priv->client->dev; int ret; + if (err && *err) + return *err; + mutex_lock(&priv->reg_lock); ret = ub960_rxport_select(priv, nport); @@ -790,16 +832,22 @@ static int ub960_rxport_update_bits(struct ub960_data *priv, u8 nport, u8 reg, out_unlock: mutex_unlock(&priv->reg_lock); + if (ret && err) + *err = ret; + return ret; } static int ub960_rxport_read16(struct ub960_data *priv, u8 nport, u8 reg, - u16 *val) + u16 *val, int *err) { struct device *dev = &priv->client->dev; __be16 __v; int ret; + if (err && *err) + return *err; + mutex_lock(&priv->reg_lock); ret = ub960_rxport_select(priv, nport); @@ -818,6 +866,9 @@ static int ub960_rxport_read16(struct ub960_data *priv, u8 nport, u8 reg, out_unlock: mutex_unlock(&priv->reg_lock); + if (ret && err) + *err = ret; + return ret; } @@ -844,12 +895,16 @@ static int ub960_txport_select(struct ub960_data *priv, u8 nport) return 0; } -static int ub960_txport_read(struct ub960_data *priv, u8 nport, u8 reg, u8 *val) +static int ub960_txport_read(struct ub960_data *priv, u8 nport, u8 reg, + u8 *val, int *err) { struct device *dev = &priv->client->dev; unsigned int v; int ret; + if (err && *err) + return *err; + mutex_lock(&priv->reg_lock); ret = ub960_txport_select(priv, nport); @@ -868,14 +923,21 @@ static int ub960_txport_read(struct ub960_data *priv, u8 nport, u8 reg, u8 *val) out_unlock: mutex_unlock(&priv->reg_lock); + if (ret && err) + *err = ret; + return ret; } -static int ub960_txport_write(struct ub960_data *priv, u8 nport, u8 reg, u8 val) +static int ub960_txport_write(struct ub960_data *priv, u8 nport, u8 reg, + u8 val, int *err) { struct device *dev = &priv->client->dev; int ret; + if (err && *err) + return *err; + mutex_lock(&priv->reg_lock); ret = ub960_txport_select(priv, nport); @@ -890,15 +952,21 @@ static int ub960_txport_write(struct ub960_data *priv, u8 nport, u8 reg, u8 val) out_unlock: mutex_unlock(&priv->reg_lock); + if (ret && err) + *err = ret; + return ret; } static int ub960_txport_update_bits(struct ub960_data *priv, u8 nport, u8 reg, - u8 mask, u8 val) + u8 mask, u8 val, int *err) { struct device *dev = &priv->client->dev; int ret; + if (err && *err) + return *err; + mutex_lock(&priv->reg_lock); ret = ub960_txport_select(priv, nport); @@ -913,6 +981,9 @@ static int ub960_txport_update_bits(struct ub960_data *priv, u8 nport, u8 reg, out_unlock: mutex_unlock(&priv->reg_lock); + if (ret && err) + *err = ret; + return ret; } @@ -938,12 +1009,16 @@ static int ub960_select_ind_reg_block(struct ub960_data *priv, u8 block) return 0; } -static int ub960_read_ind(struct ub960_data *priv, u8 block, u8 reg, u8 *val) +static int ub960_read_ind(struct ub960_data *priv, u8 block, u8 reg, u8 *val, + int *err) { struct device *dev = &priv->client->dev; unsigned int v; int ret; + if (err && *err) + return *err; + mutex_lock(&priv->reg_lock); ret = ub960_select_ind_reg_block(priv, block); @@ -971,14 +1046,21 @@ static int ub960_read_ind(struct ub960_data *priv, u8 block, u8 reg, u8 *val) out_unlock: mutex_unlock(&priv->reg_lock); + if (ret && err) + *err = ret; + return ret; } -static int ub960_write_ind(struct ub960_data *priv, u8 block, u8 reg, u8 val) +static int ub960_write_ind(struct ub960_data *priv, u8 block, u8 reg, u8 val, + int *err) { struct device *dev = &priv->client->dev; int ret; + if (err && *err) + return *err; + mutex_lock(&priv->reg_lock); ret = ub960_select_ind_reg_block(priv, block); @@ -1004,15 +1086,21 @@ static int ub960_write_ind(struct ub960_data *priv, u8 block, u8 reg, u8 val) out_unlock: mutex_unlock(&priv->reg_lock); + if (ret && err) + *err = ret; + return ret; } static int ub960_ind_update_bits(struct ub960_data *priv, u8 block, u8 reg, - u8 mask, u8 val) + u8 mask, u8 val, int *err) { struct device *dev = &priv->client->dev; int ret; + if (err && *err) + return *err; + mutex_lock(&priv->reg_lock); ret = ub960_select_ind_reg_block(priv, block); @@ -1039,6 +1127,9 @@ static int ub960_ind_update_bits(struct ub960_data *priv, u8 block, u8 reg, out_unlock: mutex_unlock(&priv->reg_lock); + if (ret && err) + *err = ret; + return ret; } @@ -1067,9 +1158,9 @@ static int ub960_atr_attach_client(struct i2c_atr *atr, u32 chan_id, rxport->aliased_clients[reg_idx] = client; ub960_rxport_write(priv, chan_id, UB960_RR_SLAVE_ID(reg_idx), - client->addr << 1); + client->addr << 1, NULL); ub960_rxport_write(priv, chan_id, UB960_RR_SLAVE_ALIAS(reg_idx), - alias << 1); + alias << 1, NULL); dev_dbg(dev, "rx%u: client 0x%02x assigned alias 0x%02x at slot %u\n", rxport->nport, client->addr, alias, reg_idx); @@ -1098,7 +1189,8 @@ static void ub960_atr_detach_client(struct i2c_atr *atr, u32 chan_id, rxport->aliased_clients[reg_idx] = NULL; - ub960_rxport_write(priv, chan_id, UB960_RR_SLAVE_ALIAS(reg_idx), 0); + ub960_rxport_write(priv, chan_id, UB960_RR_SLAVE_ALIAS(reg_idx), 0, + NULL); dev_dbg(dev, "rx%u: client 0x%02x released at slot %u\n", rxport->nport, client->addr, reg_idx); @@ -1199,7 +1291,8 @@ static void ub960_csi_handle_events(struct ub960_data *priv, u8 nport) u8 csi_tx_isr; int ret; - ret = ub960_txport_read(priv, nport, UB960_TR_CSI_TX_ISR, &csi_tx_isr); + ret = ub960_txport_read(priv, nport, UB960_TR_CSI_TX_ISR, &csi_tx_isr, + NULL); if (ret) return; @@ -1264,15 +1357,15 @@ static void ub960_rxport_clear_errors(struct ub960_data *priv, { u8 v; - ub960_rxport_read(priv, nport, UB960_RR_RX_PORT_STS1, &v); - ub960_rxport_read(priv, nport, UB960_RR_RX_PORT_STS2, &v); - ub960_rxport_read(priv, nport, UB960_RR_CSI_RX_STS, &v); - ub960_rxport_read(priv, nport, UB960_RR_BCC_STATUS, &v); + ub960_rxport_read(priv, nport, UB960_RR_RX_PORT_STS1, &v, NULL); + ub960_rxport_read(priv, nport, UB960_RR_RX_PORT_STS2, &v, NULL); + ub960_rxport_read(priv, nport, UB960_RR_CSI_RX_STS, &v, NULL); + ub960_rxport_read(priv, nport, UB960_RR_BCC_STATUS, &v, NULL); - ub960_rxport_read(priv, nport, UB960_RR_RX_PAR_ERR_HI, &v); - ub960_rxport_read(priv, nport, UB960_RR_RX_PAR_ERR_LO, &v); + ub960_rxport_read(priv, nport, UB960_RR_RX_PAR_ERR_HI, &v, NULL); + ub960_rxport_read(priv, nport, UB960_RR_RX_PAR_ERR_LO, &v, NULL); - ub960_rxport_read(priv, nport, UB960_RR_CSI_ERR_COUNTER, &v); + ub960_rxport_read(priv, nport, UB960_RR_CSI_ERR_COUNTER, &v, NULL); } static void ub960_clear_rx_errors(struct ub960_data *priv) @@ -1291,24 +1384,24 @@ static int ub960_rxport_get_strobe_pos(struct ub960_data *priv, int ret; ub960_read_ind(priv, UB960_IND_TARGET_RX_ANA(nport), - UB960_IR_RX_ANA_STROBE_SET_CLK, &v); + UB960_IR_RX_ANA_STROBE_SET_CLK, &v, NULL); clk_delay = (v & UB960_IR_RX_ANA_STROBE_SET_CLK_NO_EXTRA_DELAY) ? 0 : UB960_MANUAL_STROBE_EXTRA_DELAY; ub960_read_ind(priv, UB960_IND_TARGET_RX_ANA(nport), - UB960_IR_RX_ANA_STROBE_SET_DATA, &v); + UB960_IR_RX_ANA_STROBE_SET_DATA, &v, NULL); data_delay = (v & UB960_IR_RX_ANA_STROBE_SET_DATA_NO_EXTRA_DELAY) ? 0 : UB960_MANUAL_STROBE_EXTRA_DELAY; - ret = ub960_rxport_read(priv, nport, UB960_RR_SFILTER_STS_0, &v); + ret = ub960_rxport_read(priv, nport, UB960_RR_SFILTER_STS_0, &v, NULL); if (ret) return ret; clk_delay += v & UB960_IR_RX_ANA_STROBE_SET_CLK_DELAY_MASK; - ret = ub960_rxport_read(priv, nport, UB960_RR_SFILTER_STS_1, &v); + ret = ub960_rxport_read(priv, nport, UB960_RR_SFILTER_STS_1, &v, NULL); if (ret) return ret; @@ -1337,10 +1430,10 @@ static void ub960_rxport_set_strobe_pos(struct ub960_data *priv, data_delay = strobe_pos | UB960_IR_RX_ANA_STROBE_SET_DATA_NO_EXTRA_DELAY; ub960_write_ind(priv, UB960_IND_TARGET_RX_ANA(nport), - UB960_IR_RX_ANA_STROBE_SET_CLK, clk_delay); + UB960_IR_RX_ANA_STROBE_SET_CLK, clk_delay, NULL); ub960_write_ind(priv, UB960_IND_TARGET_RX_ANA(nport), - UB960_IR_RX_ANA_STROBE_SET_DATA, data_delay); + UB960_IR_RX_ANA_STROBE_SET_DATA, data_delay, NULL); } static void ub960_rxport_set_strobe_range(struct ub960_data *priv, @@ -1352,7 +1445,8 @@ static void ub960_rxport_set_strobe_range(struct ub960_data *priv, ub960_write(priv, UB960_XR_SFILTER_CFG, ((u8)strobe_min << UB960_XR_SFILTER_CFG_SFILTER_MIN_SHIFT) | - ((u8)strobe_max << UB960_XR_SFILTER_CFG_SFILTER_MAX_SHIFT)); + ((u8)strobe_max << UB960_XR_SFILTER_CFG_SFILTER_MAX_SHIFT), + NULL); } static int ub960_rxport_get_eq_level(struct ub960_data *priv, @@ -1361,7 +1455,7 @@ static int ub960_rxport_get_eq_level(struct ub960_data *priv, int ret; u8 v; - ret = ub960_rxport_read(priv, nport, UB960_RR_AEQ_STATUS, &v); + ret = ub960_rxport_read(priv, nport, UB960_RR_AEQ_STATUS, &v, NULL); if (ret) return ret; @@ -1386,7 +1480,7 @@ static void ub960_rxport_set_eq_level(struct ub960_data *priv, eq_stage_2_select_value = eq_level - eq_stage_max; } - ub960_rxport_read(priv, nport, UB960_RR_AEQ_BYPASS, &v); + ub960_rxport_read(priv, nport, UB960_RR_AEQ_BYPASS, &v, NULL); v &= ~(UB960_RR_AEQ_BYPASS_EQ_STAGE1_VALUE_MASK | UB960_RR_AEQ_BYPASS_EQ_STAGE2_VALUE_MASK); @@ -1394,7 +1488,7 @@ static void ub960_rxport_set_eq_level(struct ub960_data *priv, v |= eq_stage_2_select_value << UB960_RR_AEQ_BYPASS_EQ_STAGE2_VALUE_SHIFT; v |= UB960_RR_AEQ_BYPASS_ENABLE; - ub960_rxport_write(priv, nport, UB960_RR_AEQ_BYPASS, v); + ub960_rxport_write(priv, nport, UB960_RR_AEQ_BYPASS, v, NULL); } static void ub960_rxport_set_eq_range(struct ub960_data *priv, @@ -1402,12 +1496,13 @@ static void ub960_rxport_set_eq_range(struct ub960_data *priv, { ub960_rxport_write(priv, nport, UB960_RR_AEQ_MIN_MAX, (eq_min << UB960_RR_AEQ_MIN_MAX_AEQ_FLOOR_SHIFT) | - (eq_max << UB960_RR_AEQ_MIN_MAX_AEQ_MAX_SHIFT)); + (eq_max << UB960_RR_AEQ_MIN_MAX_AEQ_MAX_SHIFT), + NULL); /* Enable AEQ min setting */ ub960_rxport_update_bits(priv, nport, UB960_RR_AEQ_CTL2, UB960_RR_AEQ_CTL2_SET_AEQ_FLOOR, - UB960_RR_AEQ_CTL2_SET_AEQ_FLOOR); + UB960_RR_AEQ_CTL2_SET_AEQ_FLOOR, NULL); } static void ub960_rxport_config_eq(struct ub960_data *priv, unsigned int nport) @@ -1419,12 +1514,12 @@ static void ub960_rxport_config_eq(struct ub960_data *priv, unsigned int nport) if (priv->strobe.manual) { /* Disable AEQ_SFILTER_EN */ ub960_update_bits(priv, UB960_XR_AEQ_CTL1, - UB960_XR_AEQ_CTL1_AEQ_SFILTER_EN, 0); + UB960_XR_AEQ_CTL1_AEQ_SFILTER_EN, 0, NULL); } else { /* Enable SFILTER and error control */ ub960_write(priv, UB960_XR_AEQ_CTL1, UB960_XR_AEQ_CTL1_AEQ_ERR_CTL_MASK | - UB960_XR_AEQ_CTL1_AEQ_SFILTER_EN); + UB960_XR_AEQ_CTL1_AEQ_SFILTER_EN, NULL); /* Set AEQ strobe range */ ub960_rxport_set_strobe_range(priv, priv->strobe.min, @@ -1445,7 +1540,7 @@ static void ub960_rxport_config_eq(struct ub960_data *priv, unsigned int nport) /* Enable AEQ Bypass */ ub960_rxport_update_bits(priv, nport, UB960_RR_AEQ_BYPASS, UB960_RR_AEQ_BYPASS_ENABLE, - UB960_RR_AEQ_BYPASS_ENABLE); + UB960_RR_AEQ_BYPASS_ENABLE, NULL); } else { ub960_rxport_set_eq_range(priv, nport, rxport->eq.aeq.eq_level_min, @@ -1453,7 +1548,7 @@ static void ub960_rxport_config_eq(struct ub960_data *priv, unsigned int nport) /* Disable AEQ Bypass */ ub960_rxport_update_bits(priv, nport, UB960_RR_AEQ_BYPASS, - UB960_RR_AEQ_BYPASS_ENABLE, 0); + UB960_RR_AEQ_BYPASS_ENABLE, 0, NULL); } } @@ -1469,7 +1564,7 @@ static int ub960_rxport_link_ok(struct ub960_data *priv, unsigned int nport, bool errors; ret = ub960_rxport_read(priv, nport, UB960_RR_RX_PORT_STS1, - &rx_port_sts1); + &rx_port_sts1, NULL); if (ret) return ret; @@ -1479,25 +1574,27 @@ static int ub960_rxport_link_ok(struct ub960_data *priv, unsigned int nport, } ret = ub960_rxport_read(priv, nport, UB960_RR_RX_PORT_STS2, - &rx_port_sts2); + &rx_port_sts2, NULL); if (ret) return ret; - ret = ub960_rxport_read(priv, nport, UB960_RR_CSI_RX_STS, &csi_rx_sts); + ret = ub960_rxport_read(priv, nport, UB960_RR_CSI_RX_STS, &csi_rx_sts, + NULL); if (ret) return ret; ret = ub960_rxport_read(priv, nport, UB960_RR_CSI_ERR_COUNTER, - &csi_err_cnt); + &csi_err_cnt, NULL); if (ret) return ret; - ret = ub960_rxport_read(priv, nport, UB960_RR_BCC_STATUS, &bcc_sts); + ret = ub960_rxport_read(priv, nport, UB960_RR_BCC_STATUS, &bcc_sts, + NULL); if (ret) return ret; ret = ub960_rxport_read16(priv, nport, UB960_RR_RX_PAR_ERR_HI, - &parity_errors); + &parity_errors, NULL); if (ret) return ret; @@ -1600,7 +1697,8 @@ static int ub960_rxport_wait_locks(struct ub960_data *priv, continue; } - ub960_rxport_read16(priv, nport, UB960_RR_RX_FREQ_HIGH, &v); + ub960_rxport_read16(priv, nport, UB960_RR_RX_FREQ_HIGH, &v, + NULL); if (priv->hw_data->is_ub9702) { dev_dbg(dev, "\trx%u: locked, freq %llu Hz\n", @@ -1787,7 +1885,7 @@ static void ub960_init_tx_port(struct ub960_data *priv, if (!txport->non_continous_clk) csi_ctl |= UB960_TR_CSI_CTL_CSI_CONTS_CLOCK; - ub960_txport_write(priv, nport, UB960_TR_CSI_CTL, csi_ctl); + ub960_txport_write(priv, nport, UB960_TR_CSI_CTL, csi_ctl, NULL); } static int ub960_init_tx_ports(struct ub960_data *priv) @@ -1818,24 +1916,30 @@ static int ub960_init_tx_ports(struct ub960_data *priv) break; } - ub960_write(priv, UB960_SR_CSI_PLL_CTL, speed_select); + ub960_write(priv, UB960_SR_CSI_PLL_CTL, speed_select, NULL); if (priv->hw_data->is_ub9702) { - ub960_write(priv, UB960_SR_CSI_PLL_DIV, pll_div); + ub960_write(priv, UB960_SR_CSI_PLL_DIV, pll_div, NULL); switch (priv->tx_data_rate) { case MHZ(1600): default: - ub960_write_ind(priv, UB960_IND_TARGET_CSI_ANA, 0x92, 0x80); - ub960_write_ind(priv, UB960_IND_TARGET_CSI_ANA, 0x4b, 0x2a); + ub960_write_ind(priv, UB960_IND_TARGET_CSI_ANA, 0x92, + 0x80, NULL); + ub960_write_ind(priv, UB960_IND_TARGET_CSI_ANA, 0x4b, + 0x2a, NULL); break; case MHZ(800): - ub960_write_ind(priv, UB960_IND_TARGET_CSI_ANA, 0x92, 0x90); - ub960_write_ind(priv, UB960_IND_TARGET_CSI_ANA, 0x4f, 0x2a); - ub960_write_ind(priv, UB960_IND_TARGET_CSI_ANA, 0x4b, 0x2a); + ub960_write_ind(priv, UB960_IND_TARGET_CSI_ANA, 0x92, + 0x90, NULL); + ub960_write_ind(priv, UB960_IND_TARGET_CSI_ANA, 0x4f, + 0x2a, NULL); + ub960_write_ind(priv, UB960_IND_TARGET_CSI_ANA, 0x4b, + 0x2a, NULL); break; case MHZ(400): - ub960_write_ind(priv, UB960_IND_TARGET_CSI_ANA, 0x92, 0xa0); + ub960_write_ind(priv, UB960_IND_TARGET_CSI_ANA, 0x92, + 0xa0, NULL); break; } } @@ -1890,21 +1994,22 @@ static void ub960_init_rx_port_ub960(struct ub960_data *priv, ub960_rxport_update_bits(priv, nport, UB960_RR_BCC_CONFIG, UB960_RR_BCC_CONFIG_BC_FREQ_SEL_MASK, - bc_freq_val); + bc_freq_val, NULL); switch (rxport->rx_mode) { case RXPORT_MODE_RAW10: /* FPD3_MODE = RAW10 Mode (DS90UB913A-Q1 / DS90UB933-Q1 compatible) */ ub960_rxport_update_bits(priv, nport, UB960_RR_PORT_CONFIG, UB960_RR_PORT_CONFIG_FPD3_MODE_MASK, - 0x3); + 0x3, NULL); /* * RAW10_8BIT_CTL = 0b10 : 8-bit processing using upper 8 bits */ ub960_rxport_update_bits(priv, nport, UB960_RR_PORT_CONFIG2, UB960_RR_PORT_CONFIG2_RAW10_8BIT_CTL_MASK, - 0x2 << UB960_RR_PORT_CONFIG2_RAW10_8BIT_CTL_SHIFT); + 0x2 << UB960_RR_PORT_CONFIG2_RAW10_8BIT_CTL_SHIFT, + NULL); break; @@ -1917,33 +2022,34 @@ static void ub960_init_rx_port_ub960(struct ub960_data *priv, case RXPORT_MODE_CSI2_NONSYNC: /* CSI-2 Mode (DS90UB953-Q1 compatible) */ ub960_rxport_update_bits(priv, nport, UB960_RR_PORT_CONFIG, 0x3, - 0x0); + 0x0, NULL); break; } /* LV_POLARITY & FV_POLARITY */ ub960_rxport_update_bits(priv, nport, UB960_RR_PORT_CONFIG2, 0x3, - rxport->lv_fv_pol); + rxport->lv_fv_pol, NULL); /* Enable all interrupt sources from this port */ - ub960_rxport_write(priv, nport, UB960_RR_PORT_ICR_HI, 0x07); - ub960_rxport_write(priv, nport, UB960_RR_PORT_ICR_LO, 0x7f); + ub960_rxport_write(priv, nport, UB960_RR_PORT_ICR_HI, 0x07, NULL); + ub960_rxport_write(priv, nport, UB960_RR_PORT_ICR_LO, 0x7f, NULL); /* Enable I2C_PASS_THROUGH */ ub960_rxport_update_bits(priv, nport, UB960_RR_BCC_CONFIG, UB960_RR_BCC_CONFIG_I2C_PASS_THROUGH, - UB960_RR_BCC_CONFIG_I2C_PASS_THROUGH); + UB960_RR_BCC_CONFIG_I2C_PASS_THROUGH, NULL); /* Enable I2C communication to the serializer via the alias addr */ ub960_rxport_write(priv, nport, UB960_RR_SER_ALIAS_ID, - rxport->ser.alias << 1); + rxport->ser.alias << 1, NULL); /* Configure EQ related settings */ ub960_rxport_config_eq(priv, nport); /* Enable RX port */ - ub960_update_bits(priv, UB960_SR_RX_PORT_CTL, BIT(nport), BIT(nport)); + ub960_update_bits(priv, UB960_SR_RX_PORT_CTL, BIT(nport), BIT(nport), + NULL); } static void ub960_init_rx_port_ub9702_fpd3(struct ub960_data *priv, @@ -1984,31 +2090,36 @@ static void ub960_init_rx_port_ub9702_fpd3(struct ub960_data *priv, } ub960_rxport_update_bits(priv, nport, UB960_RR_BCC_CONFIG, 0x7, - bc_freq_val); - ub960_rxport_write(priv, nport, UB960_RR_CHANNEL_MODE, fpd_func_mode); + bc_freq_val, NULL); + ub960_rxport_write(priv, nport, UB960_RR_CHANNEL_MODE, fpd_func_mode, + NULL); /* set serdes_eq_mode = 1 */ - ub960_write_ind(priv, UB960_IND_TARGET_RX_ANA(nport), 0xa8, 0x80); + ub960_write_ind(priv, UB960_IND_TARGET_RX_ANA(nport), 0xa8, 0x80, + NULL); /* enable serdes driver */ - ub960_write_ind(priv, UB960_IND_TARGET_RX_ANA(nport), 0x0d, 0x7f); + ub960_write_ind(priv, UB960_IND_TARGET_RX_ANA(nport), 0x0d, 0x7f, + NULL); /* set serdes_eq_offset=4 */ - ub960_write_ind(priv, UB960_IND_TARGET_RX_ANA(nport), 0x2b, 0x04); + ub960_write_ind(priv, UB960_IND_TARGET_RX_ANA(nport), 0x2b, 0x04, + NULL); /* init default serdes_eq_max in 0xa9 */ - ub960_write_ind(priv, UB960_IND_TARGET_RX_ANA(nport), 0xa9, 0x23); + ub960_write_ind(priv, UB960_IND_TARGET_RX_ANA(nport), 0xa9, 0x23, + NULL); /* init serdes_eq_min in 0xaa */ - ub960_write_ind(priv, UB960_IND_TARGET_RX_ANA(nport), 0xaa, 0); + ub960_write_ind(priv, UB960_IND_TARGET_RX_ANA(nport), 0xaa, 0, NULL); /* serdes_driver_ctl2 control: DS90UB953-Q1/DS90UB933-Q1/DS90UB913A-Q1 */ ub960_ind_update_bits(priv, UB960_IND_TARGET_RX_ANA(nport), 0x1b, - BIT(3), BIT(3)); + BIT(3), BIT(3), NULL); /* RX port to half-rate */ ub960_update_bits(priv, UB960_SR_FPD_RATE_CFG, 0x3 << (nport * 2), - BIT(nport * 2)); + BIT(nport * 2), NULL); } static void ub960_init_rx_port_ub9702_fpd4_aeq(struct ub960_data *priv, @@ -2021,28 +2132,37 @@ static void ub960_init_rx_port_ub9702_fpd4_aeq(struct ub960_data *priv, u8 v; /* AEQ init */ - ub960_read_ind(priv, UB960_IND_TARGET_RX_ANA(nport), 0x2c, &v); + ub960_read_ind(priv, UB960_IND_TARGET_RX_ANA(nport), 0x2c, &v, + NULL); - ub960_write_ind(priv, UB960_IND_TARGET_RX_ANA(nport), 0x27, v); - ub960_write_ind(priv, UB960_IND_TARGET_RX_ANA(nport), 0x28, v + 1); + ub960_write_ind(priv, UB960_IND_TARGET_RX_ANA(nport), 0x27, v, + NULL); + ub960_write_ind(priv, UB960_IND_TARGET_RX_ANA(nport), 0x28, + v + 1, NULL); - ub960_write_ind(priv, UB960_IND_TARGET_RX_ANA(nport), 0x2b, 0x00); + ub960_write_ind(priv, UB960_IND_TARGET_RX_ANA(nport), 0x2b, + 0x00, NULL); } /* enable serdes_eq_ctl2 */ - ub960_write_ind(priv, UB960_IND_TARGET_RX_ANA(nport), 0x9e, 0x00); + ub960_write_ind(priv, UB960_IND_TARGET_RX_ANA(nport), 0x9e, 0x00, + NULL); /* enable serdes_eq_ctl1 */ - ub960_write_ind(priv, UB960_IND_TARGET_RX_ANA(nport), 0x90, 0x40); + ub960_write_ind(priv, UB960_IND_TARGET_RX_ANA(nport), 0x90, 0x40, + NULL); /* enable serdes_eq_en */ - ub960_write_ind(priv, UB960_IND_TARGET_RX_ANA(nport), 0x2e, 0x40); + ub960_write_ind(priv, UB960_IND_TARGET_RX_ANA(nport), 0x2e, 0x40, + NULL); /* disable serdes_eq_override */ - ub960_write_ind(priv, UB960_IND_TARGET_RX_ANA(nport), 0xf0, 0x00); + ub960_write_ind(priv, UB960_IND_TARGET_RX_ANA(nport), 0xf0, 0x00, + NULL); /* disable serdes_gain_override */ - ub960_write_ind(priv, UB960_IND_TARGET_RX_ANA(nport), 0x71, 0x00); + ub960_write_ind(priv, UB960_IND_TARGET_RX_ANA(nport), 0x71, 0x00, + NULL); } static void ub960_init_rx_port_ub9702_fpd4(struct ub960_data *priv, @@ -2077,32 +2197,38 @@ static void ub960_init_rx_port_ub9702_fpd4(struct ub960_data *priv, } ub960_rxport_update_bits(priv, nport, UB960_RR_BCC_CONFIG, 0x7, - bc_freq_val); + bc_freq_val, NULL); /* FPD4 Sync Mode */ - ub960_rxport_write(priv, nport, UB960_RR_CHANNEL_MODE, 0); + ub960_rxport_write(priv, nport, UB960_RR_CHANNEL_MODE, 0, NULL); /* add serdes_eq_offset of 4 */ - ub960_write_ind(priv, UB960_IND_TARGET_RX_ANA(nport), 0x2b, 0x04); + ub960_write_ind(priv, UB960_IND_TARGET_RX_ANA(nport), 0x2b, 0x04, + NULL); /* FPD4 serdes_start_eq in 0x27: assign default */ - ub960_write_ind(priv, UB960_IND_TARGET_RX_ANA(nport), 0x27, 0x0); + ub960_write_ind(priv, UB960_IND_TARGET_RX_ANA(nport), 0x27, 0x0, NULL); /* FPD4 serdes_end_eq in 0x28: assign default */ - ub960_write_ind(priv, UB960_IND_TARGET_RX_ANA(nport), 0x28, 0x23); + ub960_write_ind(priv, UB960_IND_TARGET_RX_ANA(nport), 0x28, 0x23, + NULL); /* set serdes_driver_mode into FPD IV mode */ - ub960_write_ind(priv, UB960_IND_TARGET_RX_ANA(nport), 0x04, 0x00); + ub960_write_ind(priv, UB960_IND_TARGET_RX_ANA(nport), 0x04, 0x00, + NULL); /* set FPD PBC drv into FPD IV mode */ - ub960_write_ind(priv, UB960_IND_TARGET_RX_ANA(nport), 0x1b, 0x00); + ub960_write_ind(priv, UB960_IND_TARGET_RX_ANA(nport), 0x1b, 0x00, + NULL); /* set serdes_system_init to 0x2f */ - ub960_write_ind(priv, UB960_IND_TARGET_RX_ANA(nport), 0x21, 0x2f); + ub960_write_ind(priv, UB960_IND_TARGET_RX_ANA(nport), 0x21, 0x2f, + NULL); /* set serdes_system_rst in reset mode */ - ub960_write_ind(priv, UB960_IND_TARGET_RX_ANA(nport), 0x25, 0xc1); + ub960_write_ind(priv, UB960_IND_TARGET_RX_ANA(nport), 0x25, 0xc1, + NULL); /* RX port to 7.55G mode */ ub960_update_bits(priv, UB960_SR_FPD_RATE_CFG, 0x3 << (nport * 2), - 0 << (nport * 2)); + 0 << (nport * 2), NULL); ub960_init_rx_port_ub9702_fpd4_aeq(priv, rxport); } @@ -2124,7 +2250,7 @@ static void ub960_init_rx_port_ub9702(struct ub960_data *priv, * 0b10 : 8-bit processing using upper 8 bits */ ub960_rxport_update_bits(priv, nport, UB960_RR_PORT_CONFIG2, - 0x3 << 6, 0x2 << 6); + 0x3 << 6, 0x2 << 6, NULL); break; @@ -2141,27 +2267,29 @@ static void ub960_init_rx_port_ub9702(struct ub960_data *priv, /* LV_POLARITY & FV_POLARITY */ ub960_rxport_update_bits(priv, nport, UB960_RR_PORT_CONFIG2, 0x3, - rxport->lv_fv_pol); + rxport->lv_fv_pol, NULL); /* Enable all interrupt sources from this port */ - ub960_rxport_write(priv, nport, UB960_RR_PORT_ICR_HI, 0x07); - ub960_rxport_write(priv, nport, UB960_RR_PORT_ICR_LO, 0x7f); + ub960_rxport_write(priv, nport, UB960_RR_PORT_ICR_HI, 0x07, NULL); + ub960_rxport_write(priv, nport, UB960_RR_PORT_ICR_LO, 0x7f, NULL); /* Enable I2C_PASS_THROUGH */ ub960_rxport_update_bits(priv, nport, UB960_RR_BCC_CONFIG, UB960_RR_BCC_CONFIG_I2C_PASS_THROUGH, - UB960_RR_BCC_CONFIG_I2C_PASS_THROUGH); + UB960_RR_BCC_CONFIG_I2C_PASS_THROUGH, NULL); /* Enable I2C communication to the serializer via the alias addr */ ub960_rxport_write(priv, nport, UB960_RR_SER_ALIAS_ID, - rxport->ser.alias << 1); + rxport->ser.alias << 1, NULL); /* Enable RX port */ - ub960_update_bits(priv, UB960_SR_RX_PORT_CTL, BIT(nport), BIT(nport)); + ub960_update_bits(priv, UB960_SR_RX_PORT_CTL, BIT(nport), BIT(nport), + NULL); if (rxport->cdr_mode == RXPORT_CDR_FPD4) { /* unreset 960 AEQ */ - ub960_write_ind(priv, UB960_IND_TARGET_RX_ANA(nport), 0x25, 0x41); + ub960_write_ind(priv, UB960_IND_TARGET_RX_ANA(nport), 0x25, + 0x41, NULL); } } @@ -2196,16 +2324,16 @@ static void ub960_rxport_handle_events(struct ub960_data *priv, u8 nport) /* Read interrupts (also clears most of them) */ if (!ret) ret = ub960_rxport_read(priv, nport, UB960_RR_RX_PORT_STS1, - &rx_port_sts1); + &rx_port_sts1, NULL); if (!ret) ret = ub960_rxport_read(priv, nport, UB960_RR_RX_PORT_STS2, - &rx_port_sts2); + &rx_port_sts2, NULL); if (!ret) ret = ub960_rxport_read(priv, nport, UB960_RR_CSI_RX_STS, - &csi_rx_sts); + &csi_rx_sts, NULL); if (!ret) ret = ub960_rxport_read(priv, nport, UB960_RR_BCC_STATUS, - &bcc_sts); + &bcc_sts, NULL); if (ret) return; @@ -2214,7 +2342,7 @@ static void ub960_rxport_handle_events(struct ub960_data *priv, u8 nport) u16 v; ret = ub960_rxport_read16(priv, nport, UB960_RR_RX_PAR_ERR_HI, - &v); + &v, NULL); if (!ret) dev_err(dev, "rx%u parity errors: %u\n", nport, v); } @@ -2273,7 +2401,8 @@ static void ub960_rxport_handle_events(struct ub960_data *priv, u8 nport) if (rx_port_sts2 & UB960_RR_RX_PORT_STS2_LINE_LEN_CHG) { u16 v; - ret = ub960_rxport_read16(priv, nport, UB960_RR_LINE_LEN_1, &v); + ret = ub960_rxport_read16(priv, nport, UB960_RR_LINE_LEN_1, + &v, NULL); if (!ret) dev_dbg(dev, "rx%u line len changed: %u\n", nport, v); } @@ -2282,7 +2411,7 @@ static void ub960_rxport_handle_events(struct ub960_data *priv, u8 nport) u16 v; ret = ub960_rxport_read16(priv, nport, UB960_RR_LINE_COUNT_HI, - &v); + &v, NULL); if (!ret) dev_dbg(dev, "rx%u line count changed: %u\n", nport, v); } @@ -2354,7 +2483,7 @@ static int ub960_enable_tx_port(struct ub960_data *priv, unsigned int nport) return ub960_txport_update_bits(priv, nport, UB960_TR_CSI_CTL, UB960_TR_CSI_CTL_CSI_ENABLE, - UB960_TR_CSI_CTL_CSI_ENABLE); + UB960_TR_CSI_CTL_CSI_ENABLE, NULL); } static void ub960_disable_tx_port(struct ub960_data *priv, unsigned int nport) @@ -2364,7 +2493,7 @@ static void ub960_disable_tx_port(struct ub960_data *priv, unsigned int nport) dev_dbg(dev, "disable TX port %u\n", nport); ub960_txport_update_bits(priv, nport, UB960_TR_CSI_CTL, - UB960_TR_CSI_CTL_CSI_ENABLE, 0); + UB960_TR_CSI_CTL_CSI_ENABLE, 0, NULL); } static int ub960_enable_rx_port(struct ub960_data *priv, unsigned int nport) @@ -2375,7 +2504,7 @@ static int ub960_enable_rx_port(struct ub960_data *priv, unsigned int nport) /* Enable forwarding */ return ub960_update_bits(priv, UB960_SR_FWD_CTL1, - UB960_SR_FWD_CTL1_PORT_DIS(nport), 0); + UB960_SR_FWD_CTL1_PORT_DIS(nport), 0, NULL); } static void ub960_disable_rx_port(struct ub960_data *priv, unsigned int nport) @@ -2387,7 +2516,7 @@ static void ub960_disable_rx_port(struct ub960_data *priv, unsigned int nport) /* Disable forwarding */ ub960_update_bits(priv, UB960_SR_FWD_CTL1, UB960_SR_FWD_CTL1_PORT_DIS(nport), - UB960_SR_FWD_CTL1_PORT_DIS(nport)); + UB960_SR_FWD_CTL1_PORT_DIS(nport), NULL); } /* @@ -2528,12 +2657,13 @@ static int ub960_configure_ports_for_streaming(struct ub960_data *priv, switch (rxport->rx_mode) { case RXPORT_MODE_RAW10: ub960_rxport_write(priv, nport, UB960_RR_RAW10_ID, - rx_data[nport].pixel_dt | (vc << UB960_RR_RAW10_ID_VC_SHIFT)); + rx_data[nport].pixel_dt | (vc << UB960_RR_RAW10_ID_VC_SHIFT), + NULL); ub960_rxport_write(priv, rxport->nport, UB960_RR_RAW_EMBED_DTYPE, (rx_data[nport].meta_lines << UB960_RR_RAW_EMBED_DTYPE_LINES_SHIFT) | - rx_data[nport].meta_dt); + rx_data[nport].meta_dt, NULL); break; @@ -2550,7 +2680,8 @@ static int ub960_configure_ports_for_streaming(struct ub960_data *priv, (vc << UB960_RR_CSI_VC_MAP_SHIFT(3)) | (vc << UB960_RR_CSI_VC_MAP_SHIFT(2)) | (vc << UB960_RR_CSI_VC_MAP_SHIFT(1)) | - (vc << UB960_RR_CSI_VC_MAP_SHIFT(0))); + (vc << UB960_RR_CSI_VC_MAP_SHIFT(0)), + NULL); } else { unsigned int i; @@ -2558,7 +2689,8 @@ static int ub960_configure_ports_for_streaming(struct ub960_data *priv, for (i = 0; i < 8; i++) ub960_rxport_write(priv, nport, UB960_RR_VC_ID_MAP(i), - (nport << 4) | nport); + (nport << 4) | nport, + NULL); } break; @@ -2570,7 +2702,7 @@ static int ub960_configure_ports_for_streaming(struct ub960_data *priv, fwd_ctl &= ~BIT(nport); /* forward to TX0 */ } - ub960_write(priv, UB960_SR_FWD_CTL1, fwd_ctl); + ub960_write(priv, UB960_SR_FWD_CTL1, fwd_ctl, NULL); return 0; } @@ -2986,7 +3118,7 @@ static void ub960_log_status_ub960_sp_eq(struct ub960_data *priv, /* Strobe */ - ret = ub960_read(priv, UB960_XR_AEQ_CTL1, &v); + ret = ub960_read(priv, UB960_XR_AEQ_CTL1, &v, NULL); if (ret) return; @@ -2995,7 +3127,7 @@ static void ub960_log_status_ub960_sp_eq(struct ub960_data *priv, "Manual"); if (v & UB960_XR_AEQ_CTL1_AEQ_SFILTER_EN) { - ret = ub960_read(priv, UB960_XR_SFILTER_CFG, &v); + ret = ub960_read(priv, UB960_XR_SFILTER_CFG, &v, NULL); if (ret) return; @@ -3012,7 +3144,7 @@ static void ub960_log_status_ub960_sp_eq(struct ub960_data *priv, /* EQ */ - ret = ub960_rxport_read(priv, nport, UB960_RR_AEQ_BYPASS, &v); + ret = ub960_rxport_read(priv, nport, UB960_RR_AEQ_BYPASS, &v, NULL); if (ret) return; @@ -3021,7 +3153,8 @@ static void ub960_log_status_ub960_sp_eq(struct ub960_data *priv, "Adaptive"); if (!(v & UB960_RR_AEQ_BYPASS_ENABLE)) { - ret = ub960_rxport_read(priv, nport, UB960_RR_AEQ_MIN_MAX, &v); + ret = ub960_rxport_read(priv, nport, UB960_RR_AEQ_MIN_MAX, &v, + NULL); if (ret) return; @@ -3047,7 +3180,7 @@ static int ub960_log_status(struct v4l2_subdev *sd) state = v4l2_subdev_lock_and_get_active_state(sd); for (unsigned int i = 0; i < sizeof(id); i++) - ub960_read(priv, UB960_SR_FPD3_RX_ID(i), &id[i]); + ub960_read(priv, UB960_SR_FPD3_RX_ID(i), &id[i], NULL); dev_info(dev, "ID '%.*s'\n", (int)sizeof(id), id); @@ -3061,20 +3194,24 @@ static int ub960_log_status(struct v4l2_subdev *sd) continue; } - ub960_txport_read(priv, nport, UB960_TR_CSI_STS, &v); + ub960_txport_read(priv, nport, UB960_TR_CSI_STS, &v, NULL); dev_info(dev, "\tsync %u, pass %u\n", v & (u8)BIT(1), v & (u8)BIT(0)); - ub960_read16(priv, UB960_SR_CSI_FRAME_COUNT_HI(nport), &v16); + ub960_read16(priv, UB960_SR_CSI_FRAME_COUNT_HI(nport), &v16, + NULL); dev_info(dev, "\tframe counter %u\n", v16); - ub960_read16(priv, UB960_SR_CSI_FRAME_ERR_COUNT_HI(nport), &v16); + ub960_read16(priv, UB960_SR_CSI_FRAME_ERR_COUNT_HI(nport), + &v16, NULL); dev_info(dev, "\tframe error counter %u\n", v16); - ub960_read16(priv, UB960_SR_CSI_LINE_COUNT_HI(nport), &v16); + ub960_read16(priv, UB960_SR_CSI_LINE_COUNT_HI(nport), &v16, + NULL); dev_info(dev, "\tline counter %u\n", v16); - ub960_read16(priv, UB960_SR_CSI_LINE_ERR_COUNT_HI(nport), &v16); + ub960_read16(priv, UB960_SR_CSI_LINE_ERR_COUNT_HI(nport), + &v16, NULL); dev_info(dev, "\tline error counter %u\n", v16); } @@ -3088,7 +3225,8 @@ static int ub960_log_status(struct v4l2_subdev *sd) continue; } - ub960_rxport_read(priv, nport, UB960_RR_RX_PORT_STS1, &v); + ub960_rxport_read(priv, nport, UB960_RR_RX_PORT_STS1, &v, + NULL); if (v & UB960_RR_RX_PORT_STS1_LOCK_STS) dev_info(dev, "\tLocked\n"); @@ -3096,22 +3234,28 @@ static int ub960_log_status(struct v4l2_subdev *sd) dev_info(dev, "\tNot locked\n"); dev_info(dev, "\trx_port_sts1 %#02x\n", v); - ub960_rxport_read(priv, nport, UB960_RR_RX_PORT_STS2, &v); + ub960_rxport_read(priv, nport, UB960_RR_RX_PORT_STS2, &v, + NULL); dev_info(dev, "\trx_port_sts2 %#02x\n", v); - ub960_rxport_read16(priv, nport, UB960_RR_RX_FREQ_HIGH, &v16); + ub960_rxport_read16(priv, nport, UB960_RR_RX_FREQ_HIGH, &v16, + NULL); dev_info(dev, "\tlink freq %llu Hz\n", ((u64)v16 * HZ_PER_MHZ) >> 8); - ub960_rxport_read16(priv, nport, UB960_RR_RX_PAR_ERR_HI, &v16); + ub960_rxport_read16(priv, nport, UB960_RR_RX_PAR_ERR_HI, &v16, + NULL); dev_info(dev, "\tparity errors %u\n", v16); - ub960_rxport_read16(priv, nport, UB960_RR_LINE_COUNT_HI, &v16); + ub960_rxport_read16(priv, nport, UB960_RR_LINE_COUNT_HI, &v16, + NULL); dev_info(dev, "\tlines per frame %u\n", v16); - ub960_rxport_read16(priv, nport, UB960_RR_LINE_LEN_1, &v16); + ub960_rxport_read16(priv, nport, UB960_RR_LINE_LEN_1, &v16, + NULL); dev_info(dev, "\tbytes per line %u\n", v16); - ub960_rxport_read(priv, nport, UB960_RR_CSI_ERR_COUNTER, &v); + ub960_rxport_read(priv, nport, UB960_RR_CSI_ERR_COUNTER, &v, + NULL); dev_info(dev, "\tcsi_err_counter %u\n", v); if (!priv->hw_data->is_ub9702) @@ -3125,7 +3269,7 @@ static int ub960_log_status(struct v4l2_subdev *sd) ctl_reg = UB960_RR_BC_GPIO_CTL(i / 2); ctl_shift = (i % 2) * 4; - ub960_rxport_read(priv, nport, ctl_reg, &v); + ub960_rxport_read(priv, nport, ctl_reg, &v, NULL); dev_info(dev, "\tGPIO%u: mode %u\n", i, (v >> ctl_shift) & 0xf); @@ -3168,13 +3312,13 @@ static irqreturn_t ub960_handle_events(int irq, void *arg) u8 fwd_sts; int ret; - ret = ub960_read(priv, UB960_SR_INTERRUPT_STS, &int_sts); + ret = ub960_read(priv, UB960_SR_INTERRUPT_STS, &int_sts, NULL); if (ret || !int_sts) return IRQ_NONE; dev_dbg(&priv->client->dev, "INTERRUPT_STS %x\n", int_sts); - ret = ub960_read(priv, UB960_SR_FWD_STS, &fwd_sts); + ret = ub960_read(priv, UB960_SR_FWD_STS, &fwd_sts, NULL); if (ret) return IRQ_NONE; @@ -3804,7 +3948,7 @@ static void ub960_reset(struct ub960_data *priv, bool reset_regs) bit = reset_regs ? UB960_SR_RESET_DIGITAL_RESET1 : UB960_SR_RESET_DIGITAL_RESET0; - ub960_write(priv, UB960_SR_RESET, bit); + ub960_write(priv, UB960_SR_RESET, bit, NULL); mutex_lock(&priv->reg_lock); @@ -3876,7 +4020,7 @@ static int ub960_enable_core_hw(struct ub960_data *priv) ub960_reset(priv, true); /* Runtime check register accessibility */ - ret = ub960_read(priv, UB960_SR_REV_MASK, &rev_mask); + ret = ub960_read(priv, UB960_SR_REV_MASK, &rev_mask, NULL); if (ret) { dev_err_probe(dev, ret, "Cannot read first register, abort\n"); goto err_pd_gpio; @@ -3885,14 +4029,16 @@ static int ub960_enable_core_hw(struct ub960_data *priv) dev_dbg(dev, "Found %s (rev/mask %#04x)\n", priv->hw_data->model, rev_mask); - ret = ub960_read(priv, UB960_SR_DEVICE_STS, &dev_sts); + ret = ub960_read(priv, UB960_SR_DEVICE_STS, &dev_sts, NULL); if (ret) goto err_pd_gpio; if (priv->hw_data->is_ub9702) - ret = ub960_read(priv, UB9702_SR_REFCLK_FREQ, &refclk_freq); + ret = ub960_read(priv, UB9702_SR_REFCLK_FREQ, &refclk_freq, + NULL); else - ret = ub960_read(priv, UB960_XR_REFCLK_FREQ, &refclk_freq); + ret = ub960_read(priv, UB960_XR_REFCLK_FREQ, &refclk_freq, + NULL); if (ret) goto err_pd_gpio; @@ -3901,7 +4047,7 @@ static int ub960_enable_core_hw(struct ub960_data *priv) clk_get_rate(priv->refclk) / HZ_PER_MHZ); /* Disable all RX ports by default */ - ret = ub960_write(priv, UB960_SR_RX_PORT_CTL, 0); + ret = ub960_write(priv, UB960_SR_RX_PORT_CTL, 0, NULL); if (ret) goto err_pd_gpio; @@ -3909,7 +4055,8 @@ static int ub960_enable_core_hw(struct ub960_data *priv) if (priv->hw_data->is_ub9702) { ret = ub960_update_bits(priv, UB960_SR_RESET, UB960_SR_RESET_GPIO_LOCK_RELEASE, - UB960_SR_RESET_GPIO_LOCK_RELEASE); + UB960_SR_RESET_GPIO_LOCK_RELEASE, + NULL); if (ret) goto err_pd_gpio; } @@ -4035,7 +4182,7 @@ static int ub960_probe(struct i2c_client *client) #ifdef UB960_DEBUG_I2C_RX_ID for (unsigned int i = 0; i < priv->hw_data->num_rxports; i++) ub960_write(priv, UB960_SR_I2C_RX_ID(i), - (UB960_DEBUG_I2C_RX_ID + i) << 1); + (UB960_DEBUG_I2C_RX_ID + i) << 1, NULL); #endif return 0; From patchwork Mon Mar 3 16:02:09 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jai Luthra X-Patchwork-Id: 870019 Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 2101521D00D; Mon, 3 Mar 2025 16:02:49 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=213.167.242.64 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741017771; cv=none; b=F1lCBxcx6IWYtvINon+IIy0kCmfcyVdmLS9faGBgY8wVjY4LN17eb/3tL2GZGAxcSMePaLJmAPT2SGoXF+wzPlUqzwYPHpFCHbJCtESxkwU0AgK+mijoWwHAfiOcsjKn01rVYiBP8J6cxt7dtBWZ/CcSWyq9si26K8UTFJHC7H0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741017771; c=relaxed/simple; bh=lwQcPFmb2dq2hmAi8n62qWMLz3ktzs7x1sphfUEvTdk=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=hUT8UES4oSCJDYJQswaCsNNJR+c05ncZ6MyLkl2LCIk141Az6vAFpw5uK1Dl5Ll6ecy7oNOTpP5BbiDceFFitvQ+QOzSty0XRf0KgGg9XUMvuS108L7cwm6iClW1mw4T5cOXvt/hNMXjavxh4i1rhmigXfSR/6Msa2XYkPgCdb4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=ideasonboard.com; spf=pass smtp.mailfrom=ideasonboard.com; dkim=pass (1024-bit key) header.d=ideasonboard.com header.i=@ideasonboard.com header.b=dR+6F9li; arc=none smtp.client-ip=213.167.242.64 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=ideasonboard.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=ideasonboard.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="dR+6F9li" Received: from mail.ideasonboard.com (unknown [IPv6:2401:4900:1c69:8872:6fe4:6987:313:70cc]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id E7CB11189; Mon, 3 Mar 2025 17:01:16 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1741017677; bh=lwQcPFmb2dq2hmAi8n62qWMLz3ktzs7x1sphfUEvTdk=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=dR+6F9li+KkeMK+n//eyMWIpUsNVM2SCwe+w+vak7KsS4SVBUPCDql4rSNsQln6/P 1KaHtx0CE41s2PsI9YfZLc9k/ajor/uSHk6JrtPBqkwDL6/SV85bn8T+GitTOMPKQw wQnUYeNn9obHTfN1rZYN8XvcizN8rdEkGS6ZITgY= From: Jai Luthra Date: Mon, 03 Mar 2025 21:32:09 +0530 Subject: [PATCH v3 06/19] media: i2c: ds90ub953: Add error handling to ub953_log_status() Precedence: bulk X-Mailing-List: linux-media@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20250303-b4-ub9xx-err-handling-v3-6-7d178796a2b9@ideasonboard.com> References: <20250303-b4-ub9xx-err-handling-v3-0-7d178796a2b9@ideasonboard.com> In-Reply-To: <20250303-b4-ub9xx-err-handling-v3-0-7d178796a2b9@ideasonboard.com> To: Mauro Carvalho Chehab , Sakari Ailus Cc: Tomi Valkeinen , Devarsh Thakkar , linux-media@vger.kernel.org, linux-kernel@vger.kernel.org, stable@vger.kernel.org, Jai Luthra X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=4286; i=jai.luthra@ideasonboard.com; h=from:subject:message-id; bh=t0xF7Xgcnsn89th/lDheR6Oc6gbB12SJ1Pi/G226hAo=; b=owEBbQKS/ZANAwAIAUPekfkkmnFFAcsmYgBnxdJ/T4oI8qyGXVOYqozHKPpzm5jaU2o9fdfGe yfB/ROSMeqJAjMEAAEIAB0WIQRN4NgY5dV16NRar8VD3pH5JJpxRQUCZ8XSfwAKCRBD3pH5JJpx RfN1EAC/uReYJluFgc/6PKJxVDYmrYuZoGhD4RsuP3B9UtxsDphRLqB8rSn3SuirrkYORasoqD8 NloK+6OIGLXXZpRKmXiOXK71BLbdkaeJsC0v8iZR49eOYkBVXmxgEzagnxLIWdioM+kQVUEUp77 4wZ8A7Xb7RhJr3NC6Jj6Ue5lhEOeBgeH4PngO1HKZy+qWH1FcR8dprDvRB2wSMqUpLhMdn9HSmB IgJM75T5pPaXN2Yj5ghiHKdIEO3J+CLiWhE+BeJhr+qvGLFytUzPvAqF/elR00xI4srBW8VUgeG yIEIpJucsVs37ewVC/XATnAl7AGeRca9wCc5h/X3IXVh7CvVWyZFxgJEP3LswCECE4KSp5SMnbq PqhXKGtGnAP/01puou3mhhzHClHqPRU/IyGg8ZO3b/oWDUVGh/0On5oDs48Lm39mNhHgOzE4shC h4vWTiHPwth4wMRHnTD5S1ICBs7r0M8P1RfxlINPvA9Msa3jgB+tTD8B5O8QUNNOkAJmRSdvGGX 8TagZrm10+cY/K9Mh4I7hhU0SuqRdPwJ+1OHcj82282X0oAEqE+fX3ADzlsZyGtYjgkZuuHG+OL wr80cmjtH7tV/s4po0j4EqMQY26g/bnNqJhCQs55KGDDRDsClSOU6y9GN7YrWXgLK03/NNdx/Vw n5ddIzcPhbhq+tQ== X-Developer-Key: i=jai.luthra@ideasonboard.com; a=openpgp; fpr=4DE0D818E5D575E8D45AAFC543DE91F9249A7145 From: Tomi Valkeinen Add error handling to ub953_log_status(). Signed-off-by: Tomi Valkeinen Signed-off-by: Jai Luthra --- drivers/media/i2c/ds90ub953.c | 80 +++++++++++++++++++++++++++++++------------ 1 file changed, 58 insertions(+), 22 deletions(-) diff --git a/drivers/media/i2c/ds90ub953.c b/drivers/media/i2c/ds90ub953.c index fbd977760c6b1ccdec90b90bced4dc29932f3893..a08aad3f7fe09f7b396da9c720ed9993d392410c 100644 --- a/drivers/media/i2c/ds90ub953.c +++ b/drivers/media/i2c/ds90ub953.c @@ -633,23 +633,33 @@ static int ub953_log_status(struct v4l2_subdev *sd) { struct ub953_data *priv = sd_to_ub953(sd); struct device *dev = &priv->client->dev; - u8 v = 0, v1 = 0, v2 = 0; - unsigned int i; char id[UB953_REG_FPD3_RX_ID_LEN]; - u8 gpio_local_data = 0; - u8 gpio_input_ctrl = 0; - u8 gpio_pin_sts = 0; + u8 gpio_local_data; + u8 gpio_input_ctrl; + u8 gpio_pin_sts; + unsigned int i; + u8 v, v1, v2; + int ret; - for (i = 0; i < sizeof(id); i++) - ub953_read(priv, UB953_REG_FPD3_RX_ID(i), &id[i], NULL); + for (i = 0; i < sizeof(id); i++) { + ret = ub953_read(priv, UB953_REG_FPD3_RX_ID(i), &id[i], NULL); + if (ret) + return ret; + } dev_info(dev, "ID '%.*s'\n", (int)sizeof(id), id); - ub953_read(priv, UB953_REG_GENERAL_STATUS, &v, NULL); + ret = ub953_read(priv, UB953_REG_GENERAL_STATUS, &v, NULL); + if (ret) + return ret; + dev_info(dev, "GENERAL_STATUS %#02x\n", v); - ub953_read(priv, UB953_REG_CRC_ERR_CNT1, &v1, NULL); - ub953_read(priv, UB953_REG_CRC_ERR_CNT2, &v2, NULL); + ub953_read(priv, UB953_REG_CRC_ERR_CNT1, &v1, &ret); + ub953_read(priv, UB953_REG_CRC_ERR_CNT2, &v2, &ret); + if (ret) + return ret; + dev_info(dev, "CRC error count %u\n", v1 | (v2 << 8)); /* Clear CRC error counter */ @@ -658,34 +668,60 @@ static int ub953_log_status(struct v4l2_subdev *sd) UB953_REG_BC_CTRL_CRC_ERR_CLR, UB953_REG_BC_CTRL_CRC_ERR_CLR); - ub953_read(priv, UB953_REG_CSI_ERR_CNT, &v, NULL); + ret = ub953_read(priv, UB953_REG_CSI_ERR_CNT, &v, NULL); + if (ret) + return ret; + dev_info(dev, "CSI error count %u\n", v); - ub953_read(priv, UB953_REG_CSI_ERR_STATUS, &v, NULL); + ret = ub953_read(priv, UB953_REG_CSI_ERR_STATUS, &v, NULL); + if (ret) + return ret; + dev_info(dev, "CSI_ERR_STATUS %#02x\n", v); - ub953_read(priv, UB953_REG_CSI_ERR_DLANE01, &v, NULL); + ret = ub953_read(priv, UB953_REG_CSI_ERR_DLANE01, &v, NULL); + if (ret) + return ret; + dev_info(dev, "CSI_ERR_DLANE01 %#02x\n", v); - ub953_read(priv, UB953_REG_CSI_ERR_DLANE23, &v, NULL); + ret = ub953_read(priv, UB953_REG_CSI_ERR_DLANE23, &v, NULL); + if (ret) + return ret; + dev_info(dev, "CSI_ERR_DLANE23 %#02x\n", v); - ub953_read(priv, UB953_REG_CSI_ERR_CLK_LANE, &v, NULL); + ret = ub953_read(priv, UB953_REG_CSI_ERR_CLK_LANE, &v, NULL); + if (ret) + return ret; + dev_info(dev, "CSI_ERR_CLK_LANE %#02x\n", v); - ub953_read(priv, UB953_REG_CSI_PKT_HDR_VC_ID, &v, NULL); + ret = ub953_read(priv, UB953_REG_CSI_PKT_HDR_VC_ID, &v, NULL); + if (ret) + return ret; + dev_info(dev, "CSI packet header VC %u ID %u\n", v >> 6, v & 0x3f); - ub953_read(priv, UB953_REG_PKT_HDR_WC_LSB, &v1, NULL); - ub953_read(priv, UB953_REG_PKT_HDR_WC_MSB, &v2, NULL); + ub953_read(priv, UB953_REG_PKT_HDR_WC_LSB, &v1, &ret); + ub953_read(priv, UB953_REG_PKT_HDR_WC_MSB, &v2, &ret); + if (ret) + return ret; + dev_info(dev, "CSI packet header WC %u\n", (v2 << 8) | v1); - ub953_read(priv, UB953_REG_CSI_ECC, &v, NULL); + ret = ub953_read(priv, UB953_REG_CSI_ECC, &v, NULL); + if (ret) + return ret; + dev_info(dev, "CSI ECC %#02x\n", v); - ub953_read(priv, UB953_REG_LOCAL_GPIO_DATA, &gpio_local_data, NULL); - ub953_read(priv, UB953_REG_GPIO_INPUT_CTRL, &gpio_input_ctrl, NULL); - ub953_read(priv, UB953_REG_GPIO_PIN_STS, &gpio_pin_sts, NULL); + ub953_read(priv, UB953_REG_LOCAL_GPIO_DATA, &gpio_local_data, &ret); + ub953_read(priv, UB953_REG_GPIO_INPUT_CTRL, &gpio_input_ctrl, &ret); + ub953_read(priv, UB953_REG_GPIO_PIN_STS, &gpio_pin_sts, &ret); + if (ret) + return ret; for (i = 0; i < UB953_NUM_GPIOS; i++) { dev_info(dev, From patchwork Mon Mar 3 16:02:10 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jai Luthra X-Patchwork-Id: 870018 Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4478621D00D; Mon, 3 Mar 2025 16:02:55 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=213.167.242.64 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741017776; cv=none; b=COb8FrfDiwDrrfnXS4TnqCDly2KGySmcUKJ55gcXrTYpD3Q/M/bk09shAY4LuzsusmDckdCq3rOjwoUATY0l8JvteEcWDDrJlW+2r88743zwyq3tgyYlZndlriApEcklQ1UU4jmHa9iA/4XvAu4pJCjbONaU7pmOKKnTPZ1BTIc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741017776; c=relaxed/simple; bh=YGNcpfecclFHsUxiBA262QSa31eZiUPpvs7Xod/t+R4=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=utbytm6n+kwPoSpzqt8NtsmT0QXJb00wB0I5brjIhwnci2Gdh7ttpF0ZY/9hza313VFBRfTiaeiklLzaYN2JmX31noQ0e5R2LBEYGeBompuWg17YL9cc8RwxkXxnkTcfySUlvJsMk+qd7VasJg0LAwIcmGj98sO3LTzqdjx5x8A= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=ideasonboard.com; spf=pass smtp.mailfrom=ideasonboard.com; dkim=pass (1024-bit key) header.d=ideasonboard.com header.i=@ideasonboard.com header.b=PIlfh3nD; arc=none smtp.client-ip=213.167.242.64 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=ideasonboard.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=ideasonboard.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="PIlfh3nD" Received: from mail.ideasonboard.com (unknown [IPv6:2401:4900:1c69:8872:6fe4:6987:313:70cc]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 1CBB21189; Mon, 3 Mar 2025 17:01:21 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1741017682; bh=YGNcpfecclFHsUxiBA262QSa31eZiUPpvs7Xod/t+R4=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=PIlfh3nDOlUwoz02C0N6SFzfsseXOAZX1+z4aWxI7MNCm8EiIN7K91Ws9R/Nr89P3 z4qAesf1AbxY7JWIQq0MEvDSym6k3eB054LBdL1GpjKoelaX6+V/neTabfNBTgY9jt rHSIUcYo3s+0HDGxpuaqYsCJSIEpeTIwgOwehjEw= From: Jai Luthra Date: Mon, 03 Mar 2025 21:32:10 +0530 Subject: [PATCH v3 07/19] media: i2c: ds90ub913: Add error handling to ub913_log_status() Precedence: bulk X-Mailing-List: linux-media@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20250303-b4-ub9xx-err-handling-v3-7-7d178796a2b9@ideasonboard.com> References: <20250303-b4-ub9xx-err-handling-v3-0-7d178796a2b9@ideasonboard.com> In-Reply-To: <20250303-b4-ub9xx-err-handling-v3-0-7d178796a2b9@ideasonboard.com> To: Mauro Carvalho Chehab , Sakari Ailus Cc: Tomi Valkeinen , Devarsh Thakkar , linux-media@vger.kernel.org, linux-kernel@vger.kernel.org, stable@vger.kernel.org, Jai Luthra X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=2117; i=jai.luthra@ideasonboard.com; h=from:subject:message-id; bh=7IJDzezFLx1eVHMvd2PtZf75W4/IFV+34VaoTHVKehc=; b=owEBbQKS/ZANAwAIAUPekfkkmnFFAcsmYgBnxdJ/ih4C/2QW9VkIjBlUwlD0rlMxR82Yh1Q7b tbjz3ORQZeJAjMEAAEIAB0WIQRN4NgY5dV16NRar8VD3pH5JJpxRQUCZ8XSfwAKCRBD3pH5JJpx RUuiEACbE+eSyNbHYJbiIaI9/KZaCF5jHeOAVUPu/X8T6lqsSeRDC2IkSRxFnyilSNXJLTZSl1u pTqiVu1C39s4E0ZrJY1DGidRCkrsZddmhkjmYiuTMn99oqiwUJ2lnQS0VRb5ua/t1OcQki/in36 fiV7KJS5pyXqL+vOmW5ZmvYieGRleMBGVaCLyZiQWh412rysBr4uvuKQkIseKD0oUOWO+Lq+4Yp RRRiq1y22dxxEDoboopPwNKuMr8MzVkM0YFX9MWnoXhgGy8r4aYMQEimXXo7udMvPhXlM4EoepT Xgc0Q5M9q4BR1PYjQqlM7Www813rePN7C/gze1445YqIo71fatgzUUr5kJNlZiLpVaq/PZtk9X9 fID2Em/R4/VqBAsm9eC9QGek0w0Y6b6hB+jXaVV9q1cgWx+KRcq6wbHl7l6cCaUJAbz1ixDpzfk oh1bPaaC3ZN7O4bdzGg0pZP7BJRS5e6j4NSRXIIUxX3UHUnkl0E2fSl0eUWMgPedUXsM8s6zauh Yr1/ODQvMxwL1Apm2xZ2rL7u+l/qQ1LLOCi0qF0kOaBbbZwJtfG3upIXYJQM7A1ZEKceRbjlzFi 975EklO2o2vtX4a9S9Luw5l8pzEMtvWFv7GstPkK8OcDFUoi8M8eW6MDlsvFzEqZ1Fw2bELom7a l2p0BpHgCP274ZQ== X-Developer-Key: i=jai.luthra@ideasonboard.com; a=openpgp; fpr=4DE0D818E5D575E8D45AAFC543DE91F9249A7145 From: Tomi Valkeinen Add error handling to ub913_log_status(). Signed-off-by: Tomi Valkeinen Signed-off-by: Jai Luthra --- drivers/media/i2c/ds90ub913.c | 34 +++++++++++++++++++++++++--------- 1 file changed, 25 insertions(+), 9 deletions(-) diff --git a/drivers/media/i2c/ds90ub913.c b/drivers/media/i2c/ds90ub913.c index f38421d34d204fa9ab898d10c6b69942858bced2..401cc2a10c3c9855b1875b2ff200d5109e80b2e0 100644 --- a/drivers/media/i2c/ds90ub913.c +++ b/drivers/media/i2c/ds90ub913.c @@ -504,25 +504,41 @@ static int ub913_log_status(struct v4l2_subdev *sd) { struct ub913_data *priv = sd_to_ub913(sd); struct device *dev = &priv->client->dev; - u8 v = 0, v1 = 0, v2 = 0; + u8 v, v1, v2; + int ret; + + ret = ub913_read(priv, UB913_REG_MODE_SEL, &v, NULL); + if (ret) + return ret; - ub913_read(priv, UB913_REG_MODE_SEL, &v, NULL); dev_info(dev, "MODE_SEL %#02x\n", v); - ub913_read(priv, UB913_REG_CRC_ERRORS_LSB, &v1, NULL); - ub913_read(priv, UB913_REG_CRC_ERRORS_MSB, &v2, NULL); + ub913_read(priv, UB913_REG_CRC_ERRORS_LSB, &v1, &ret); + ub913_read(priv, UB913_REG_CRC_ERRORS_MSB, &v2, &ret); + if (ret) + return ret; + dev_info(dev, "CRC errors %u\n", v1 | (v2 << 8)); /* clear CRC errors */ - ub913_read(priv, UB913_REG_GENERAL_CFG, &v, NULL); + ub913_read(priv, UB913_REG_GENERAL_CFG, &v, &ret); ub913_write(priv, UB913_REG_GENERAL_CFG, - v | UB913_REG_GENERAL_CFG_CRC_ERR_RESET, NULL); - ub913_write(priv, UB913_REG_GENERAL_CFG, v, NULL); + v | UB913_REG_GENERAL_CFG_CRC_ERR_RESET, &ret); + ub913_write(priv, UB913_REG_GENERAL_CFG, v, &ret); + + if (ret) + return ret; + + ret = ub913_read(priv, UB913_REG_GENERAL_STATUS, &v, NULL); + if (ret) + return ret; - ub913_read(priv, UB913_REG_GENERAL_STATUS, &v, NULL); dev_info(dev, "GENERAL_STATUS %#02x\n", v); - ub913_read(priv, UB913_REG_PLL_OVR, &v, NULL); + ret = ub913_read(priv, UB913_REG_PLL_OVR, &v, NULL); + if (ret) + return ret; + dev_info(dev, "PLL_OVR %#02x\n", v); return 0; From patchwork Mon Mar 3 16:02:12 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jai Luthra X-Patchwork-Id: 870017 Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D5A10214A93; Mon, 3 Mar 2025 16:03:05 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=213.167.242.64 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741017787; cv=none; b=L3nnAGb4gnyDfDq7uVeqb1f4doqD81ZBcoPKa4iRQZinQTBYtgSAwZrtfwzOY0D5ey8lxHSy5d5AQ/U4CAeji1N4Eq87O+rXgagtdEOC5LMUJT1bbJTzYw6X5L+FyyCwQgfGh7vq9uTClr7X5W1f+JAutk5oYPi87hLckq1037U= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741017787; c=relaxed/simple; bh=r6QgWYf401NOa9KkoAhiZK5TU+mf3VFZJPP5qiDTYuE=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=gY04q0jmr4v7NnHyfCd093+WDXJ409AjxH4aXvH5n1tN3UHutgpWQbfaFzHfFHbouDXxGIhMwuY+RVB9xUbdyW4ToiNNYEyceGiKNM3HweMeQrxMn4oExisjyDm5Mw6eAZpwc0G0Hvtdjsb1O9ktKPpbd2LTM/dqaI4RTcqXytE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=ideasonboard.com; spf=pass smtp.mailfrom=ideasonboard.com; dkim=pass (1024-bit key) header.d=ideasonboard.com header.i=@ideasonboard.com header.b=A71GGNw4; arc=none smtp.client-ip=213.167.242.64 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=ideasonboard.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=ideasonboard.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="A71GGNw4" Received: from mail.ideasonboard.com (unknown [IPv6:2401:4900:1c69:8872:6fe4:6987:313:70cc]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id C7C8111E9; Mon, 3 Mar 2025 17:01:32 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1741017693; bh=r6QgWYf401NOa9KkoAhiZK5TU+mf3VFZJPP5qiDTYuE=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=A71GGNw4GNkB5adV8MNlxlScpTyws4MKbXf+o0+ywk4dr8KBC99QQXrs8ZHBzHjdJ ucEvdqPwXMVeHSiOBpTnVWqwmVX2xBEuPN9xmWG0ZvuOGYeRAZwMVoD5uFSNz1JAOK caVBM2h4px5JnmC5eNg5EfFCwovQ0vlT//YJB5r0= From: Jai Luthra Date: Mon, 03 Mar 2025 21:32:12 +0530 Subject: [PATCH v3 09/19] media: i2c: ds90ub960: Move UB9702 registers to a separate section Precedence: bulk X-Mailing-List: linux-media@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20250303-b4-ub9xx-err-handling-v3-9-7d178796a2b9@ideasonboard.com> References: <20250303-b4-ub9xx-err-handling-v3-0-7d178796a2b9@ideasonboard.com> In-Reply-To: <20250303-b4-ub9xx-err-handling-v3-0-7d178796a2b9@ideasonboard.com> To: Mauro Carvalho Chehab , Sakari Ailus Cc: Tomi Valkeinen , Devarsh Thakkar , linux-media@vger.kernel.org, linux-kernel@vger.kernel.org, stable@vger.kernel.org, Jai Luthra X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=4413; i=jai.luthra@ideasonboard.com; h=from:subject:message-id; bh=IXL5dSwbgPveyVgafIS7q5lVNIBo7+BRNM1+9mJTPLU=; b=owEBbQKS/ZANAwAIAUPekfkkmnFFAcsmYgBnxdJ/XElP6asDwOFeaI5YNSw8epK7dONxHdyBV DtPM3Zs402JAjMEAAEIAB0WIQRN4NgY5dV16NRar8VD3pH5JJpxRQUCZ8XSfwAKCRBD3pH5JJpx RWVhEADBqsb2gIgQ8LYgVdD3P0GVMXueYLt9pVec1yui7fxy2O6jN4qPO+zAwikbaFZZMJOTxZI ILXitNdzzMyBDXcSVlTRYNBXhBItaoXBb0g8bpGyKOPW8HluFokj+NjgPOSPZiuWhrg1lZ+G9A7 R90ILOdON3/nbQyp3jOgxOeP3hh+Y9xqueUxaVxFL/rYVGSTyCt8wZurxJrMaw1W4ts4/5PIHCr xdHleOU3zqC+OEvqEukR0plxEl11Sm1rYBIdsag3nUOr4NZYAdiJhLK6BTfXMDxCImXYET2pf6M rikoe/dIZS5ufiQxLTGOY8sbxzvMd3bfOsO7wpOlcDgMjZp1Y53P0SNZu7QVDcK5yu3Hbj+a+nS PxXBaKlsPE9PfUoxxrYXQBqctk/skRHiJg6Ydvq+H3hyZRlrQUFLaRnegNAZa+Ig3LjBO4BdgEA JCmMw5U39r/1RjjKTC9171fl4EM5ED3xDTz18Tb23zwWllG1pQO+h2uYT7Dm1ewkGy4XNzG0gxI 1TWvIW9gCFaMLAklg1X1kolV3ju3oB4r2T6xDaVAgveD8/BfTv+ZM65jJK4qKbmpY0igs/dDzfC gJoMBqt6wNrpJ5pbKv0769Pes0eM625C6uHwmJ2ReO0M+biRWCSRdsyZCrkLy0oIe6I16RPYRcz fvEhpm6Mi0P03EA== X-Developer-Key: i=jai.luthra@ideasonboard.com; a=openpgp; fpr=4DE0D818E5D575E8D45AAFC543DE91F9249A7145 From: Tomi Valkeinen The driver supports both UB960 and UB9702. While devices work in similar ways and have a lot of identical registers, there are also plenty of differences. To clarify the situation a bit, move the UB9702 registers to a separate section and prefix them with UB9702. Signed-off-by: Tomi Valkeinen Signed-off-by: Jai Luthra --- drivers/media/i2c/ds90ub960.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/drivers/media/i2c/ds90ub960.c b/drivers/media/i2c/ds90ub960.c index 086aa8cc78fa4e4e9ccc08589cbaf1cc06104786..f9af6d643ac86de22286b2107d747341c7d6f9b0 100644 --- a/drivers/media/i2c/ds90ub960.c +++ b/drivers/media/i2c/ds90ub960.c @@ -307,8 +307,6 @@ #define UB960_XR_REFCLK_FREQ 0xa5 /* UB960 */ -#define UB960_RR_VC_ID_MAP(x) (0xa0 + (x)) /* UB9702 */ - #define UB960_SR_IND_ACC_CTL 0xb0 #define UB960_SR_IND_ACC_CTL_IA_AUTO_INC BIT(1) @@ -321,9 +319,6 @@ #define UB960_SR_FV_MIN_TIME 0xbc #define UB960_SR_GPIO_PD_CTL 0xbe -#define UB960_SR_FPD_RATE_CFG 0xc2 /* UB9702 */ -#define UB960_SR_CSI_PLL_DIV 0xc9 /* UB9702 */ - #define UB960_RR_PORT_DEBUG 0xd0 #define UB960_RR_AEQ_CTL2 0xd2 #define UB960_RR_AEQ_CTL2_SET_AEQ_FLOOR BIT(2) @@ -354,15 +349,12 @@ #define UB960_RR_SEN_INT_RISE_STS 0xde #define UB960_RR_SEN_INT_FALL_STS 0xdf -#define UB960_RR_CHANNEL_MODE 0xe4 /* UB9702 */ #define UB960_SR_FPD3_RX_ID(n) (0xf0 + (n)) #define UB960_SR_FPD3_RX_ID_LEN 6 #define UB960_SR_I2C_RX_ID(n) (0xf8 + (n)) -#define UB9702_SR_REFCLK_FREQ 0x3d - /* Indirect register blocks */ #define UB960_IND_TARGET_PAT_GEN 0x00 #define UB960_IND_TARGET_RX_ANA(n) (0x01 + (n)) @@ -397,6 +389,14 @@ #define UB960_IR_RX_ANA_STROBE_SET_DATA_NO_EXTRA_DELAY BIT(3) #define UB960_IR_RX_ANA_STROBE_SET_DATA_DELAY_MASK GENMASK(2, 0) +/* UB9702 Registers */ + +#define UB9702_SR_REFCLK_FREQ 0x3d +#define UB9702_RR_VC_ID_MAP(x) (0xa0 + (x)) +#define UB9702_SR_FPD_RATE_CFG 0xc2 +#define UB9702_SR_CSI_PLL_DIV 0xc9 +#define UB9702_RR_CHANNEL_MODE 0xe4 + /* EQ related */ #define UB960_MIN_AEQ_STROBE_POS -7 @@ -1989,7 +1989,7 @@ static int ub960_init_tx_ports(struct ub960_data *priv) ub960_write(priv, UB960_SR_CSI_PLL_CTL, speed_select, &ret); if (priv->hw_data->is_ub9702) { - ub960_write(priv, UB960_SR_CSI_PLL_DIV, pll_div, &ret); + ub960_write(priv, UB9702_SR_CSI_PLL_DIV, pll_div, &ret); switch (priv->tx_data_rate) { case MHZ(1600): @@ -2170,7 +2170,7 @@ static int ub960_init_rx_port_ub9702_fpd3(struct ub960_data *priv, ub960_rxport_update_bits(priv, nport, UB960_RR_BCC_CONFIG, 0x7, bc_freq_val, &ret); - ub960_rxport_write(priv, nport, UB960_RR_CHANNEL_MODE, fpd_func_mode, + ub960_rxport_write(priv, nport, UB9702_RR_CHANNEL_MODE, fpd_func_mode, &ret); /* set serdes_eq_mode = 1 */ @@ -2197,7 +2197,7 @@ static int ub960_init_rx_port_ub9702_fpd3(struct ub960_data *priv, BIT(3), BIT(3), &ret); /* RX port to half-rate */ - ub960_update_bits(priv, UB960_SR_FPD_RATE_CFG, 0x3 << (nport * 2), + ub960_update_bits(priv, UB9702_SR_FPD_RATE_CFG, 0x3 << (nport * 2), BIT(nport * 2), &ret); return ret; @@ -2285,7 +2285,7 @@ static int ub960_init_rx_port_ub9702_fpd4(struct ub960_data *priv, bc_freq_val, &ret); /* FPD4 Sync Mode */ - ub960_rxport_write(priv, nport, UB960_RR_CHANNEL_MODE, 0, &ret); + ub960_rxport_write(priv, nport, UB9702_RR_CHANNEL_MODE, 0, &ret); /* add serdes_eq_offset of 4 */ ub960_write_ind(priv, UB960_IND_TARGET_RX_ANA(nport), 0x2b, 0x04, @@ -2312,7 +2312,7 @@ static int ub960_init_rx_port_ub9702_fpd4(struct ub960_data *priv, &ret); /* RX port to 7.55G mode */ - ub960_update_bits(priv, UB960_SR_FPD_RATE_CFG, 0x3 << (nport * 2), + ub960_update_bits(priv, UB9702_SR_FPD_RATE_CFG, 0x3 << (nport * 2), 0 << (nport * 2), &ret); if (ret) @@ -2786,7 +2786,7 @@ static int ub960_configure_ports_for_streaming(struct ub960_data *priv, /* Map all VCs from this port to VC(nport) */ for (i = 0; i < 8; i++) ub960_rxport_write(priv, nport, - UB960_RR_VC_ID_MAP(i), + UB9702_RR_VC_ID_MAP(i), (nport << 4) | nport, &ret); } From patchwork Mon Mar 3 16:02:14 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jai Luthra X-Patchwork-Id: 870016 Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8D3C1214A93; Mon, 3 Mar 2025 16:03:17 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=213.167.242.64 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741017799; cv=none; b=ILqFbUm9lOXOoK+ZRWQ5Gl5FGtsyl8DKDDmHorcBbQDlFF3GBt7I9CwND6rBe7cZ6nX48M18SO+XT0W4NFoh4zKLUj/o6q/hEfoBfiklhYx+wks+FXkXAnx8vn+iNElaVr5+5cfPQwj3wvaHWfHg1russ/t2CcDs5t01wPhoeeo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741017799; c=relaxed/simple; bh=qT0me5iVNf3kIvTDXcq8PN3s6ZFmMwgXJJVomJwLVJk=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=pTf/9XTAKlGWXaokUfbOXwGxP7MHEXrtO4noTCrmoPO4zrctdhy/T4pz6XQgJSwn7mXVThMDLEZkRpFxopd8dqjx0kAGUYTFhQe+H/VjmxRPUZ3cwmv6tmKRO61GxGKoCcw5812zRMsSnaNdSuYqNj47G82bOcRW8MW2g704rnA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=ideasonboard.com; spf=pass smtp.mailfrom=ideasonboard.com; dkim=pass (1024-bit key) header.d=ideasonboard.com header.i=@ideasonboard.com header.b=hxO7jRtr; arc=none smtp.client-ip=213.167.242.64 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=ideasonboard.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=ideasonboard.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="hxO7jRtr" Received: from mail.ideasonboard.com (unknown [IPv6:2401:4900:1c69:8872:6fe4:6987:313:70cc]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 67CC922A; Mon, 3 Mar 2025 17:01:44 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1741017704; bh=qT0me5iVNf3kIvTDXcq8PN3s6ZFmMwgXJJVomJwLVJk=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=hxO7jRtrdZUuSj1rv/wZYjx2kpf2nDXr8FCqC3w4xZaJ2l+5KhVkW4z5rcmAGr2XP WTXnUA19rfO7t3IJTL668xTI4Lxa0FRw3bCeeOCbvZfUpKu7YI0RwIxH4rJ6na0Ltu GGXJRPCJNskRi5HADxsB5rKuLkZajXquk+7KyXy8= From: Jai Luthra Date: Mon, 03 Mar 2025 21:32:14 +0530 Subject: [PATCH v3 11/19] media: i2c: ds90ub960: Split ub960_init_tx_ports() Precedence: bulk X-Mailing-List: linux-media@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20250303-b4-ub9xx-err-handling-v3-11-7d178796a2b9@ideasonboard.com> References: <20250303-b4-ub9xx-err-handling-v3-0-7d178796a2b9@ideasonboard.com> In-Reply-To: <20250303-b4-ub9xx-err-handling-v3-0-7d178796a2b9@ideasonboard.com> To: Mauro Carvalho Chehab , Sakari Ailus Cc: Tomi Valkeinen , Devarsh Thakkar , linux-media@vger.kernel.org, linux-kernel@vger.kernel.org, stable@vger.kernel.org, Jai Luthra X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=3935; i=jai.luthra@ideasonboard.com; h=from:subject:message-id; bh=NnmWv2EiSSc1ctQfgNC7cyCxt+VEUaW1p9KFGj4+kBg=; b=owEBbQKS/ZANAwAIAUPekfkkmnFFAcsmYgBnxdJ/aItO1MVgnAkqiO8p7XR316WMRH5Vg3I/G 9L/pZsY0EyJAjMEAAEIAB0WIQRN4NgY5dV16NRar8VD3pH5JJpxRQUCZ8XSfwAKCRBD3pH5JJpx RVHYEACMLA3hxnj2aSHLYrwDFvQwb+2MET5A+yzSRESY1f3+kRoCsTzvU9W1EKeyhrx5WbmuMJO 1mAyEKRMLQtN5/yjLArKVRVS/MSEU9Qn0hxLAFvtUOPHVFwQZWluKI8OzJOv9GnEmuzr1wqZzTy ej9q7yROwRlhp56A+tu71CPmrJEBLDH+ocwBZAK/SR/GGWaAvOOOfWIH+u1qaE/C5LodkNx9y6P 2ifSypXpPHtz7K1lJ1CnK+5YmO88kqhPq8qQCVM/WZbbWD0yDWnO1eG0e5EWvKi1vk1Ctnc0GBv 2aFNf8Crl+WOMeKxjo9PAzIKN+KJD5sQKpJ/mO/FNJv2OpLCRn9TWcwkz69VMSJ1XwWprYnb3ST xr2uAKGbzQhQG1+B/bHwPlOmPMvsOBABV3hxCL+exrmymaJRKq46LdDojTQw+Desm72SEtPOfSX Fd/2wVcmEfByBmLOB4fmH4srczcX2I6l/QESgkesIEFKB2yXmn1rbNZfYAGxBpgNsCrCcK+kowt fspScPXbDQfQFmtRe8rwAMV/VvgBH9fLuMyXmtGcPdXGArcc7sQaj1yNG615TiCipkS+aW0tlDU ZFOF4tfYkXYsCWV3o7hxHr6XyNZeTC1GPz7HEBH1KWb2nEWcxaPtbTRVOuMUJGJZ/BEuqSaGjr4 Bf9yZxVoOFmVmLw== X-Developer-Key: i=jai.luthra@ideasonboard.com; a=openpgp; fpr=4DE0D818E5D575E8D45AAFC543DE91F9249A7145 From: Tomi Valkeinen Split ub960_init_tx_ports() to a UB960 and a UB9702 versions to make it easier to update the UB9702 version in the following patch. No funcional changes. Signed-off-by: Tomi Valkeinen Signed-off-by: Jai Luthra --- drivers/media/i2c/ds90ub960.c | 105 +++++++++++++++++++++++++++--------------- 1 file changed, 68 insertions(+), 37 deletions(-) diff --git a/drivers/media/i2c/ds90ub960.c b/drivers/media/i2c/ds90ub960.c index c56398aa895f05029879fb336bc52c932fee494d..579ca570a543a9ee8be8f9d4432a2da8fa09e54d 100644 --- a/drivers/media/i2c/ds90ub960.c +++ b/drivers/media/i2c/ds90ub960.c @@ -1992,67 +1992,98 @@ static int ub960_init_tx_port(struct ub960_data *priv, return ub960_txport_write(priv, nport, UB960_TR_CSI_CTL, csi_ctl, NULL); } -static int ub960_init_tx_ports(struct ub960_data *priv) +static int ub960_init_tx_ports_ub960(struct ub960_data *priv) { - unsigned int nport; u8 speed_select; - u8 pll_div; - int ret = 0; - - /* TX ports */ switch (priv->tx_data_rate) { + case MHZ(400): + speed_select = 3; + break; + case MHZ(800): + speed_select = 2; + break; + case MHZ(1200): + speed_select = 1; + break; case MHZ(1600): default: speed_select = 0; - pll_div = 0x10; break; - case MHZ(1200): - speed_select = 1; - pll_div = 0x18; + } + + return ub960_write(priv, UB960_SR_CSI_PLL_CTL, speed_select, NULL); +} + +static int ub960_init_tx_ports_ub9702(struct ub960_data *priv) +{ + u8 speed_select; + u8 pll_div; + int ret = 0; + + switch (priv->tx_data_rate) { + case MHZ(400): + speed_select = 3; + pll_div = 0x10; break; case MHZ(800): speed_select = 2; pll_div = 0x10; break; - case MHZ(400): - speed_select = 3; + case MHZ(1200): + speed_select = 1; + pll_div = 0x18; + break; + case MHZ(1600): + default: + speed_select = 0; pll_div = 0x10; break; } ub960_write(priv, UB960_SR_CSI_PLL_CTL, speed_select, &ret); - if (priv->hw_data->is_ub9702) { - ub960_write(priv, UB9702_SR_CSI_PLL_DIV, pll_div, &ret); - - switch (priv->tx_data_rate) { - case MHZ(1600): - default: - ub960_write_ind(priv, UB960_IND_TARGET_CSI_ANA, 0x92, - 0x80, &ret); - ub960_write_ind(priv, UB960_IND_TARGET_CSI_ANA, 0x4b, - 0x2a, &ret); - break; - case MHZ(800): - ub960_write_ind(priv, UB960_IND_TARGET_CSI_ANA, 0x92, - 0x90, &ret); - ub960_write_ind(priv, UB960_IND_TARGET_CSI_ANA, 0x4f, - 0x2a, &ret); - ub960_write_ind(priv, UB960_IND_TARGET_CSI_ANA, 0x4b, - 0x2a, &ret); - break; - case MHZ(400): - ub960_write_ind(priv, UB960_IND_TARGET_CSI_ANA, 0x92, - 0xa0, &ret); - break; - } + ub960_write(priv, UB9702_SR_CSI_PLL_DIV, pll_div, &ret); + + switch (priv->tx_data_rate) { + case MHZ(1600): + default: + ub960_write_ind(priv, UB960_IND_TARGET_CSI_ANA, 0x92, 0x80, + &ret); + ub960_write_ind(priv, UB960_IND_TARGET_CSI_ANA, 0x4b, 0x2a, + &ret); + break; + case MHZ(800): + ub960_write_ind(priv, UB960_IND_TARGET_CSI_ANA, 0x92, 0x90, + &ret); + ub960_write_ind(priv, UB960_IND_TARGET_CSI_ANA, 0x4f, 0x2a, + &ret); + ub960_write_ind(priv, UB960_IND_TARGET_CSI_ANA, 0x4b, 0x2a, + &ret); + break; + case MHZ(400): + ub960_write_ind(priv, UB960_IND_TARGET_CSI_ANA, 0x92, 0xa0, + &ret); + break; } + return ret; +} + +static int ub960_init_tx_ports(struct ub960_data *priv) +{ + int ret; + + if (priv->hw_data->is_ub9702) + ret = ub960_init_tx_ports_ub9702(priv); + else + ret = ub960_init_tx_ports_ub960(priv); + if (ret) return ret; - for (nport = 0; nport < priv->hw_data->num_txports; nport++) { + for (unsigned int nport = 0; nport < priv->hw_data->num_txports; + nport++) { struct ub960_txport *txport = priv->txports[nport]; if (!txport) From patchwork Mon Mar 3 16:02:16 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jai Luthra X-Patchwork-Id: 870015 Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 661CA22F15C; Mon, 3 Mar 2025 16:03:26 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=213.167.242.64 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741017808; cv=none; b=dH7jmIzxXeDzBLWw0TmbKB7ZbpbrdbK2qm3az0fDBrNEisPpNOYAOk6AIb+2utCYWQyoYEEnzReSA9D4HgXQ6YE2o04fdzrvkISUYd/XBGjAHagJq22QH/5gltdJLc6lMwdxnK4BpBxNOBS8zTsmTy4CvmiWMPnNwL6E3QH6uyw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741017808; c=relaxed/simple; bh=ye8T+T4AXwPste1Az6Che5D8l2fjCzBWR4bJUTUi+/s=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Ly9Kb9nLOj7Z8xWPr7ZQDpI54R04ggPGytlcuI7XuBr3UCvOyrq470/HzQ5M+Vx+D8jW/4sEapVhPfGiNVCEnEMiq1WBtthJkzw4Og78Z+EDa5im9V50sWD8WzgLrIzrXqDjb/8yUzrpao0VXcIV9KuxOsqQJd+8qouTfYJfPpU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=ideasonboard.com; spf=pass smtp.mailfrom=ideasonboard.com; dkim=pass (1024-bit key) header.d=ideasonboard.com header.i=@ideasonboard.com header.b=lyeF5+ut; arc=none smtp.client-ip=213.167.242.64 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=ideasonboard.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=ideasonboard.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="lyeF5+ut" Received: from mail.ideasonboard.com (unknown [IPv6:2401:4900:1c69:8872:6fe4:6987:313:70cc]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 4B27A22A; Mon, 3 Mar 2025 17:01:53 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1741017713; bh=ye8T+T4AXwPste1Az6Che5D8l2fjCzBWR4bJUTUi+/s=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=lyeF5+utEbzIV+vcaWWght6KHUl0BkFHWJO8Axh2+9zh04f3nAU/34TJPVeloJoPy pHlCjoK063qrSomKdKhq3SUckLudAN3MQfMO+RAADd4e63HEQF6CdIkYmEHpr+XblI r6RXFQ//rxkjQ2fw9vAJBf/4fOJBd8otlQRwjxKc= From: Jai Luthra Date: Mon, 03 Mar 2025 21:32:16 +0530 Subject: [PATCH v3 13/19] media: i2c: ds90ub960: Add RX port iteration support Precedence: bulk X-Mailing-List: linux-media@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20250303-b4-ub9xx-err-handling-v3-13-7d178796a2b9@ideasonboard.com> References: <20250303-b4-ub9xx-err-handling-v3-0-7d178796a2b9@ideasonboard.com> In-Reply-To: <20250303-b4-ub9xx-err-handling-v3-0-7d178796a2b9@ideasonboard.com> To: Mauro Carvalho Chehab , Sakari Ailus Cc: Tomi Valkeinen , Devarsh Thakkar , linux-media@vger.kernel.org, linux-kernel@vger.kernel.org, stable@vger.kernel.org, Jai Luthra X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=18261; i=jai.luthra@ideasonboard.com; h=from:subject:message-id; bh=wWAjZLtJT+WKoPfOIxOIcMMHIgFjvwRC9w3PQnCsPk8=; b=owEBbQKS/ZANAwAIAUPekfkkmnFFAcsmYgBnxdKAxyeaeaYZKfi72g7xpxbDaGRMuVpL9/+PQ +2NOD4kT7SJAjMEAAEIAB0WIQRN4NgY5dV16NRar8VD3pH5JJpxRQUCZ8XSgAAKCRBD3pH5JJpx Rb6zEADEDk8AOZgbKTlSr1OMcr4gLJ+bGmNENrvkqZiDiF5/jHrhgdYKsV571AMk+2A0uLnWuZT l/Y/7a2mjGfXhJrJ5t0EfKUrQgL5pyAcOE6S8636KQDBzbVw1XzF9zB8EHsvzqwLoHJxN7J6fbH AdSOXhc2v3pGuEkB1xTc44kH/xLqHjLlvV1R9k/FJ/2fKxeU4vI3L70qV4e/ADUByCE7R/+gpTO hE1w7BR11CI2HhDuaR/7bqx8jy2qqVOQ75UN6Ps2oUSZSqMUSsx0B+o72oezIKeoRCbVIQjOKy2 7Oqf/TwzZCxf85QQa6W/v5h5YBLgaClE+1WDeO74qGGnJBcNSOVV8tcaFI+fUqKRAf6G6gWMV5s whijNCm5fNcg3hUXYkWs0hKe9lMiE2uXLtXwM2tbCaI6h5oprmPLHRFNy2eVSyjIAlaG1winGLm cJBkFHmYMr/QUshXD8mw3qJEbVWL38G1NMTT6aqGxAS9MP7Bp/wyxMUbsehf6nrNli1BLRAg1uH jxu1PhJnrvWkpVXCXu9p/r7u75TIevAx6zYE0kY5NRU5i6ZAYP6gVs2cV69uKojN92/WW5MLaSZ jQvEs893MRiIM4oM4xxclWpbW2nBzPRBWXoraYt6Lp92fFnKxnu3iYjAwGt92wbpa8eU2ZnW1oE bIoEriWTw+c/tOQ== X-Developer-Key: i=jai.luthra@ideasonboard.com; a=openpgp; fpr=4DE0D818E5D575E8D45AAFC543DE91F9249A7145 From: Tomi Valkeinen The driver does a lot of iteration over the RX ports with for loops. In most cases the driver will skip unused RX ports. Also, in the future patches the FPD-Link IV support will be refreshed with TI's latest init sequences which involves a lot of additional iterations over the RX ports, often only for FPD-Link IV ports. To make the iteration simpler and to make it clearer what we're iterating over (all or only-active, all or only-fpd4), add macros and support functions for iterating the RX ports. Use the macros in the driver, replacing the for loops. Signed-off-by: Tomi Valkeinen Signed-off-by: Jai Luthra --- drivers/media/i2c/ds90ub960.c | 260 ++++++++++++++++++++++-------------------- 1 file changed, 135 insertions(+), 125 deletions(-) diff --git a/drivers/media/i2c/ds90ub960.c b/drivers/media/i2c/ds90ub960.c index ed49508d2b79283a95f2f3315b53f21d4301b089..af7ba1c824b12893bd31bed7a88a6e3bf8a62f7e 100644 --- a/drivers/media/i2c/ds90ub960.c +++ b/drivers/media/i2c/ds90ub960.c @@ -649,6 +649,63 @@ static const struct ub960_format_info *ub960_find_format(u32 code) return NULL; } +struct ub960_rxport_iter { + unsigned int nport; + struct ub960_rxport *rxport; +}; + +enum ub960_iter_flags { + UB960_ITER_ACTIVE_ONLY = BIT(0), + UB960_ITER_FPD4_ONLY = BIT(1), +}; + +static struct ub960_rxport_iter ub960_iter_rxport(struct ub960_data *priv, + struct ub960_rxport_iter it, + enum ub960_iter_flags flags) +{ + for (; it.nport < priv->hw_data->num_rxports; it.nport++) { + it.rxport = priv->rxports[it.nport]; + + if ((flags & UB960_ITER_ACTIVE_ONLY) && !it.rxport) + continue; + + if ((flags & UB960_ITER_FPD4_ONLY) && + it.rxport->cdr_mode != RXPORT_CDR_FPD4) + continue; + + return it; + } + + it.rxport = NULL; + + return it; +} + +#define for_each_rxport(priv, it) \ + for (struct ub960_rxport_iter it = \ + ub960_iter_rxport(priv, (struct ub960_rxport_iter){ 0 }, \ + 0); \ + it.nport < (priv)->hw_data->num_rxports; \ + it.nport++, it = ub960_iter_rxport(priv, it, 0)) + +#define for_each_active_rxport(priv, it) \ + for (struct ub960_rxport_iter it = \ + ub960_iter_rxport(priv, (struct ub960_rxport_iter){ 0 }, \ + UB960_ITER_ACTIVE_ONLY); \ + it.nport < (priv)->hw_data->num_rxports; \ + it.nport++, it = ub960_iter_rxport(priv, it, \ + UB960_ITER_ACTIVE_ONLY)) + +#define for_each_active_rxport_fpd4(priv, it) \ + for (struct ub960_rxport_iter it = \ + ub960_iter_rxport(priv, (struct ub960_rxport_iter){ 0 }, \ + UB960_ITER_ACTIVE_ONLY | \ + UB960_ITER_FPD4_ONLY); \ + it.nport < (priv)->hw_data->num_rxports; \ + it.nport++, it = ub960_iter_rxport(priv, it, \ + UB960_ITER_ACTIVE_ONLY | \ + UB960_ITER_FPD4_ONLY)) + /* ----------------------------------------------------------------------------- * Basic device access */ @@ -1356,25 +1413,25 @@ static int ub960_csi_handle_events(struct ub960_data *priv, u8 nport) static int ub960_rxport_enable_vpocs(struct ub960_data *priv) { - unsigned int nport; + unsigned int failed_nport; int ret; - for (nport = 0; nport < priv->hw_data->num_rxports; nport++) { - struct ub960_rxport *rxport = priv->rxports[nport]; - - if (!rxport || !rxport->vpoc) + for_each_active_rxport(priv, it) { + if (!it.rxport->vpoc) continue; - ret = regulator_enable(rxport->vpoc); - if (ret) + ret = regulator_enable(it.rxport->vpoc); + if (ret) { + failed_nport = it.nport; goto err_disable_vpocs; + } } return 0; err_disable_vpocs: - while (nport--) { - struct ub960_rxport *rxport = priv->rxports[nport]; + while (failed_nport--) { + struct ub960_rxport *rxport = priv->rxports[failed_nport]; if (!rxport || !rxport->vpoc) continue; @@ -1387,15 +1444,11 @@ static int ub960_rxport_enable_vpocs(struct ub960_data *priv) static void ub960_rxport_disable_vpocs(struct ub960_data *priv) { - unsigned int nport; - - for (nport = 0; nport < priv->hw_data->num_rxports; nport++) { - struct ub960_rxport *rxport = priv->rxports[nport]; - - if (!rxport || !rxport->vpoc) + for_each_active_rxport(priv, it) { + if (!it.rxport->vpoc) continue; - regulator_disable(rxport->vpoc); + regulator_disable(it.rxport->vpoc); } } @@ -1420,12 +1473,10 @@ static int ub960_rxport_clear_errors(struct ub960_data *priv, static int ub960_clear_rx_errors(struct ub960_data *priv) { - unsigned int nport; - - for (nport = 0; nport < priv->hw_data->num_rxports; nport++) { - int ret; + int ret; - ret = ub960_rxport_clear_errors(priv, nport); + for_each_rxport(priv, it) { + ret = ub960_rxport_clear_errors(priv, it.nport); if (ret) return ret; } @@ -1928,30 +1979,27 @@ static void ub960_rxport_remove_serializer(struct ub960_data *priv, u8 nport) /* Add serializer i2c devices for all initialized ports */ static int ub960_rxport_add_serializers(struct ub960_data *priv) { - unsigned int nport; + unsigned int failed_nport; int ret; - for (nport = 0; nport < priv->hw_data->num_rxports; nport++) { - struct ub960_rxport *rxport = priv->rxports[nport]; - - if (!rxport) - continue; - - ret = ub960_rxport_add_serializer(priv, nport); - if (ret) + for_each_active_rxport(priv, it) { + ret = ub960_rxport_add_serializer(priv, it.nport); + if (ret) { + failed_nport = it.nport; goto err_remove_sers; + } } return 0; err_remove_sers: - while (nport--) { - struct ub960_rxport *rxport = priv->rxports[nport]; + while (failed_nport--) { + struct ub960_rxport *rxport = priv->rxports[failed_nport]; if (!rxport) continue; - ub960_rxport_remove_serializer(priv, nport); + ub960_rxport_remove_serializer(priv, failed_nport); } return ret; @@ -1959,16 +2007,8 @@ static int ub960_rxport_add_serializers(struct ub960_data *priv) static void ub960_rxport_remove_serializers(struct ub960_data *priv) { - unsigned int nport; - - for (nport = 0; nport < priv->hw_data->num_rxports; nport++) { - struct ub960_rxport *rxport = priv->rxports[nport]; - - if (!rxport) - continue; - - ub960_rxport_remove_serializer(priv, nport); - } + for_each_active_rxport(priv, it) + ub960_rxport_remove_serializer(priv, it.nport); } static int ub960_init_tx_port(struct ub960_data *priv, @@ -2453,19 +2493,13 @@ static int ub960_init_rx_port_ub9702(struct ub960_data *priv, static int ub960_init_rx_ports(struct ub960_data *priv) { - unsigned int nport; - - for (nport = 0; nport < priv->hw_data->num_rxports; nport++) { - struct ub960_rxport *rxport = priv->rxports[nport]; + for_each_active_rxport(priv, it) { int ret; - if (!rxport) - continue; - if (priv->hw_data->is_ub9702) - ret = ub960_init_rx_port_ub9702(priv, rxport); + ret = ub960_init_rx_port_ub9702(priv, it.rxport); else - ret = ub960_init_rx_port_ub960(priv, rxport); + ret = ub960_init_rx_port_ub960(priv, it.rxport); if (ret) return ret; @@ -2683,20 +2717,14 @@ static int ub960_disable_rx_port(struct ub960_data *priv, unsigned int nport) */ static int ub960_validate_stream_vcs(struct ub960_data *priv) { - unsigned int nport; - unsigned int i; - - for (nport = 0; nport < priv->hw_data->num_rxports; nport++) { - struct ub960_rxport *rxport = priv->rxports[nport]; + for_each_active_rxport(priv, it) { struct v4l2_mbus_frame_desc desc; int ret; u8 vc; - if (!rxport) - continue; - - ret = v4l2_subdev_call(rxport->source.sd, pad, get_frame_desc, - rxport->source.pad, &desc); + ret = v4l2_subdev_call(it.rxport->source.sd, pad, + get_frame_desc, it.rxport->source.pad, + &desc); if (ret) return ret; @@ -2708,13 +2736,13 @@ static int ub960_validate_stream_vcs(struct ub960_data *priv) vc = desc.entry[0].bus.csi2.vc; - for (i = 1; i < desc.num_entries; i++) { + for (unsigned int i = 1; i < desc.num_entries; i++) { if (vc == desc.entry[i].bus.csi2.vc) continue; dev_err(&priv->client->dev, "rx%u: source with multiple virtual-channels is not supported\n", - nport); + it.nport); return -ENODEV; } } @@ -2804,21 +2832,21 @@ static int ub960_configure_ports_for_streaming(struct ub960_data *priv, */ fwd_ctl = GENMASK(7, 4); - for (unsigned int nport = 0; nport < priv->hw_data->num_rxports; - nport++) { - struct ub960_rxport *rxport = priv->rxports[nport]; + for_each_active_rxport(priv, it) { + unsigned long nport = it.nport; + u8 vc = vc_map[nport]; if (rx_data[nport].num_streams == 0) continue; - switch (rxport->rx_mode) { + switch (it.rxport->rx_mode) { case RXPORT_MODE_RAW10: ub960_rxport_write(priv, nport, UB960_RR_RAW10_ID, rx_data[nport].pixel_dt | (vc << UB960_RR_RAW10_ID_VC_SHIFT), &ret); - ub960_rxport_write(priv, rxport->nport, + ub960_rxport_write(priv, nport, UB960_RR_RAW_EMBED_DTYPE, (rx_data[nport].meta_lines << UB960_RR_RAW_EMBED_DTYPE_LINES_SHIFT) | rx_data[nport].meta_dt, &ret); @@ -2886,7 +2914,6 @@ static int ub960_enable_streams(struct v4l2_subdev *sd, u64 sink_streams[UB960_MAX_RX_NPORTS] = {}; struct v4l2_subdev_route *route; unsigned int failed_port; - unsigned int nport; int ret; if (!priv->streaming) { @@ -2908,6 +2935,8 @@ static int ub960_enable_streams(struct v4l2_subdev *sd, /* Collect sink streams per pad which we need to enable */ for_each_active_route(&state->routing, route) { + unsigned int nport; + if (route->source_pad != source_pad) continue; @@ -2919,7 +2948,9 @@ static int ub960_enable_streams(struct v4l2_subdev *sd, sink_streams[nport] |= BIT_ULL(route->sink_stream); } - for (nport = 0; nport < priv->hw_data->num_rxports; nport++) { + for_each_rxport(priv, it) { + unsigned int nport = it.nport; + if (!sink_streams[nport]) continue; @@ -2957,7 +2988,7 @@ static int ub960_enable_streams(struct v4l2_subdev *sd, return 0; err: - for (nport = 0; nport < failed_port; nport++) { + for (unsigned int nport = 0; nport < failed_port; nport++) { if (!sink_streams[nport]) continue; @@ -2997,11 +3028,12 @@ static int ub960_disable_streams(struct v4l2_subdev *sd, struct device *dev = &priv->client->dev; u64 sink_streams[UB960_MAX_RX_NPORTS] = {}; struct v4l2_subdev_route *route; - unsigned int nport; int ret; /* Collect sink streams per pad which we need to disable */ for_each_active_route(&state->routing, route) { + unsigned int nport; + if (route->source_pad != source_pad) continue; @@ -3013,7 +3045,9 @@ static int ub960_disable_streams(struct v4l2_subdev *sd, sink_streams[nport] |= BIT_ULL(route->sink_stream); } - for (nport = 0; nport < priv->hw_data->num_rxports; nport++) { + for_each_rxport(priv, it) { + unsigned int nport = it.nport; + if (!sink_streams[nport]) continue; @@ -3335,7 +3369,6 @@ static int ub960_log_status(struct v4l2_subdev *sd) struct ub960_data *priv = sd_to_ub960(sd); struct device *dev = &priv->client->dev; struct v4l2_subdev_state *state; - unsigned int nport; u16 v16 = 0; u8 v = 0; u8 id[UB960_SR_FPD3_RX_ID_LEN]; @@ -3351,7 +3384,8 @@ static int ub960_log_status(struct v4l2_subdev *sd) dev_info(dev, "ID '%.*s'\n", (int)sizeof(id), id); - for (nport = 0; nport < priv->hw_data->num_txports; nport++) { + for (unsigned int nport = 0; nport < priv->hw_data->num_txports; + nport++) { struct ub960_txport *txport = priv->txports[nport]; dev_info(dev, "TX %u\n", nport); @@ -3397,12 +3431,12 @@ static int ub960_log_status(struct v4l2_subdev *sd) dev_info(dev, "\tline error counter %u\n", v16); } - for (nport = 0; nport < priv->hw_data->num_rxports; nport++) { - struct ub960_rxport *rxport = priv->rxports[nport]; + for_each_rxport(priv, it) { + unsigned int nport = it.nport; dev_info(dev, "RX %u\n", nport); - if (!rxport) { + if (!it.rxport) { dev_info(dev, "\tNot initialized\n"); continue; } @@ -3514,7 +3548,6 @@ static const struct media_entity_operations ub960_entity_ops = { static irqreturn_t ub960_handle_events(int irq, void *arg) { struct ub960_data *priv = arg; - unsigned int i; u8 int_sts; u8 fwd_sts; int ret; @@ -3531,7 +3564,7 @@ static irqreturn_t ub960_handle_events(int irq, void *arg) dev_dbg(&priv->client->dev, "FWD_STS %#02x\n", fwd_sts); - for (i = 0; i < priv->hw_data->num_txports; i++) { + for (unsigned int i = 0; i < priv->hw_data->num_txports; i++) { if (int_sts & UB960_SR_INTERRUPT_STS_IS_CSI_TX(i)) { ret = ub960_csi_handle_events(priv, i); if (ret) @@ -3539,12 +3572,9 @@ static irqreturn_t ub960_handle_events(int irq, void *arg) } } - for (i = 0; i < priv->hw_data->num_rxports; i++) { - if (!priv->rxports[i]) - continue; - - if (int_sts & UB960_SR_INTERRUPT_STS_IS_RX(i)) { - ret = ub960_rxport_handle_events(priv, i); + for_each_active_rxport(priv, it) { + if (int_sts & UB960_SR_INTERRUPT_STS_IS_RX(it.nport)) { + ret = ub960_rxport_handle_events(priv, it.nport); if (ret) return IRQ_NONE; } @@ -3582,19 +3612,12 @@ static void ub960_txport_free_ports(struct ub960_data *priv) static void ub960_rxport_free_ports(struct ub960_data *priv) { - unsigned int nport; - - for (nport = 0; nport < priv->hw_data->num_rxports; nport++) { - struct ub960_rxport *rxport = priv->rxports[nport]; - - if (!rxport) - continue; - - fwnode_handle_put(rxport->source.ep_fwnode); - fwnode_handle_put(rxport->ser.fwnode); + for_each_active_rxport(priv, it) { + fwnode_handle_put(it.rxport->source.ep_fwnode); + fwnode_handle_put(it.rxport->ser.fwnode); - kfree(rxport); - priv->rxports[nport] = NULL; + kfree(it.rxport); + priv->rxports[it.nport] = NULL; } } @@ -3853,7 +3876,6 @@ static int ub960_parse_dt_rxports(struct ub960_data *priv) { struct device *dev = &priv->client->dev; struct fwnode_handle *links_fwnode; - unsigned int nport; int ret; links_fwnode = fwnode_get_named_child_node(dev_fwnode(dev), "links"); @@ -3868,9 +3890,10 @@ static int ub960_parse_dt_rxports(struct ub960_data *priv) priv->strobe.manual = fwnode_property_read_bool(links_fwnode, "ti,manual-strobe"); - for (nport = 0; nport < priv->hw_data->num_rxports; nport++) { + for_each_rxport(priv, it) { struct fwnode_handle *link_fwnode; struct fwnode_handle *ep_fwnode; + unsigned int nport = it.nport; link_fwnode = ub960_fwnode_get_link_by_regs(links_fwnode, nport); if (!link_fwnode) @@ -3959,7 +3982,6 @@ static int ub960_notify_bound(struct v4l2_async_notifier *notifier, struct ub960_rxport *rxport = to_ub960_asd(asd)->rxport; struct device *dev = &priv->client->dev; u8 nport = rxport->nport; - unsigned int i; int ret; ret = media_entity_get_fwnode_pad(&subdev->entity, @@ -3984,8 +4006,8 @@ static int ub960_notify_bound(struct v4l2_async_notifier *notifier, return ret; } - for (i = 0; i < priv->hw_data->num_rxports; i++) { - if (priv->rxports[i] && !priv->rxports[i]->source.sd) { + for_each_active_rxport(priv, it) { + if (!it.rxport->source.sd) { dev_dbg(dev, "Waiting for more subdevs to be bound\n"); return 0; } @@ -4011,29 +4033,24 @@ static const struct v4l2_async_notifier_operations ub960_notify_ops = { static int ub960_v4l2_notifier_register(struct ub960_data *priv) { struct device *dev = &priv->client->dev; - unsigned int i; int ret; v4l2_async_subdev_nf_init(&priv->notifier, &priv->sd); - for (i = 0; i < priv->hw_data->num_rxports; i++) { - struct ub960_rxport *rxport = priv->rxports[i]; + for_each_active_rxport(priv, it) { struct ub960_asd *asd; - if (!rxport) - continue; - asd = v4l2_async_nf_add_fwnode(&priv->notifier, - rxport->source.ep_fwnode, + it.rxport->source.ep_fwnode, struct ub960_asd); if (IS_ERR(asd)) { dev_err(dev, "Failed to add subdev for source %u: %pe", - i, asd); + it.nport, asd); v4l2_async_nf_cleanup(&priv->notifier); return PTR_ERR(asd); } - asd->rxport = rxport; + asd->rxport = it.rxport; } priv->notifier.ops = &ub960_notify_ops; @@ -4304,7 +4321,6 @@ static int ub960_probe(struct i2c_client *client) struct ub960_data *priv; unsigned int port_lock_mask; unsigned int port_mask; - unsigned int nport; int ret; priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); @@ -4357,14 +4373,8 @@ static int ub960_probe(struct i2c_client *client) port_mask = 0; - for (nport = 0; nport < priv->hw_data->num_rxports; nport++) { - struct ub960_rxport *rxport = priv->rxports[nport]; - - if (!rxport) - continue; - - port_mask |= BIT(nport); - } + for_each_active_rxport(priv, it) + port_mask |= BIT(it.nport); ret = ub960_rxport_wait_locks(priv, port_mask, &port_lock_mask); if (ret) @@ -4403,9 +4413,9 @@ static int ub960_probe(struct i2c_client *client) msecs_to_jiffies(UB960_POLL_TIME_MS)); #ifdef UB960_DEBUG_I2C_RX_ID - for (unsigned int i = 0; i < priv->hw_data->num_rxports; i++) - ub960_write(priv, UB960_SR_I2C_RX_ID(i), - (UB960_DEBUG_I2C_RX_ID + i) << 1, NULL); + for_each_rxport(priv, it) + ub960_write(priv, UB960_SR_I2C_RX_ID(it.nport), + (UB960_DEBUG_I2C_RX_ID + it.nport) << 1, NULL); #endif return 0; From patchwork Mon Mar 3 16:02:18 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jai Luthra X-Patchwork-Id: 870014 Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C957822FE07; Mon, 3 Mar 2025 16:03:37 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=213.167.242.64 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741017820; cv=none; b=WUcEf7wBcJo/VvZkPCN3+xkNmdqTYf7OxDosrwdCWkOO5vA9/xpSYyFo824INynk5VfJLHQDYHcQAb3WY54ZKas9nqpm34A+MKMHexaRtDHNfxG7sIUv91Udje3a2Pa+i5NV0dZy59TQOEVv8BmkgwlyiqIEIZBE3lzDARTyeDU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741017820; c=relaxed/simple; bh=L7X41F0uguy6iOJvm0D0JCeQ5W1EeTlos0Q00eBOQ2o=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=MspFuDBCdO7laDktejsHEF0U7BA8tqnTczI+osfd3hJExV1eFta6jAJoEwm5ZEi0We4slV0HOhcwdyZsEOtVhBzNmJlORHMxKiZ5glFyeakiOHz7XLC6TE38die8E+/5M39DjOYfaZHh3hubzg4/Vn7mmwzuySUOm+IRauJzj/o= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=ideasonboard.com; spf=pass smtp.mailfrom=ideasonboard.com; dkim=pass (1024-bit key) header.d=ideasonboard.com header.i=@ideasonboard.com header.b=SbFEGTre; arc=none smtp.client-ip=213.167.242.64 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=ideasonboard.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=ideasonboard.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="SbFEGTre" Received: from mail.ideasonboard.com (unknown [IPv6:2401:4900:1c69:8872:6fe4:6987:313:70cc]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 91E1422A; Mon, 3 Mar 2025 17:02:04 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1741017725; bh=L7X41F0uguy6iOJvm0D0JCeQ5W1EeTlos0Q00eBOQ2o=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=SbFEGTreFL7iiQ2Amb/w31anaDYVoVxoeiLzln+QWZdjIogxHIH5FgtIzp08hHSzn HUd994Vs7w1mCrN0Cc8Ht9yPUPAV1zgFdBGfxz6aLfqGqqfYKFHjnx5XM80oCtrSQV xf81DxhJpJBNyb0c0QEhqZLVu3KBWSZxXmEHxLm0= From: Jai Luthra Date: Mon, 03 Mar 2025 21:32:18 +0530 Subject: [PATCH v3 15/19] media: i2c: ds90ub960: Update UB9702 init sequences Precedence: bulk X-Mailing-List: linux-media@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20250303-b4-ub9xx-err-handling-v3-15-7d178796a2b9@ideasonboard.com> References: <20250303-b4-ub9xx-err-handling-v3-0-7d178796a2b9@ideasonboard.com> In-Reply-To: <20250303-b4-ub9xx-err-handling-v3-0-7d178796a2b9@ideasonboard.com> To: Mauro Carvalho Chehab , Sakari Ailus Cc: Tomi Valkeinen , Devarsh Thakkar , linux-media@vger.kernel.org, linux-kernel@vger.kernel.org, stable@vger.kernel.org, Jai Luthra X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=29509; i=jai.luthra@ideasonboard.com; h=from:subject:message-id; bh=OtovcZBPo9uFG+pd5+5n4GjLHAnYe/FIURneQQywdbY=; b=owEBbQKS/ZANAwAIAUPekfkkmnFFAcsmYgBnxdKA3EncLxWcS2pkp8YzXqC8w+lsLslUqT/Cr jOqv5mMCraJAjMEAAEIAB0WIQRN4NgY5dV16NRar8VD3pH5JJpxRQUCZ8XSgAAKCRBD3pH5JJpx RfJfD/9Sjr/PBOqS7CfF/NTeNlrGhj3QxS4Ho3lDoqviSULCDohZNGwe2B7lneZAEb8gk2Xst+4 TKYbV3sqvoIeZ3lTZEa0mla4/tTiFINUGe/0NnJoeUMYEeysCg6FJCHdw/jmfMU8LN9KrzDohFl A29eZ9iFpi05j6XzcmRsHHkSNDYg/Cx3+eDpbAQP83Rdu+kpomzZYtpKrOsVx9A93N42SODpT+5 HNpru2pcLn+wDQN7j5nBeW/1ikoE7c1XKw/mQHFZHoJrB+7WJjUUFP8Mrktah60nXp0mCLUpMKX WwdHYOSO6JGTl+OCROFQSXipwWV+LJJ6pjh+YhoTF6TD4HVLf9fw16zIlMVJHxOXDag156v/+zx z7H6E95ylfHGtzdA0RSt4WbjzLWp5ilabYbgf987zjM53A6hTjy7MPIWPAxl6/t+VPhy+KBanAN nTCJ9j2HOVge1jgOOR1nUw6hjKuEJc7XxDrWTiHawlug51w/lmAozUgjplGyIgP5vLcO537ZLFc mVRiSqMOhgyi+w4X0si3nLdxG3rpnft5Ca4Y6goUJko7c872lC380teBqijT1wkCjVa3e3/0DsW x6jqMfnM+SKLo1DPC+B19LvTiX1AUKHiBxFlr+n4EnUbJYnDfwzYo4paSiWe1sv+DNedIntr1aa 7cKaiYYWQRZrAIQ== X-Developer-Key: i=jai.luthra@ideasonboard.com; a=openpgp; fpr=4DE0D818E5D575E8D45AAFC543DE91F9249A7145 From: Tomi Valkeinen Update ub9702 RX port init sequence according to TI's latest (non-public) documentation. The sequence is based on a Python script provided by TI. Signed-off-by: Tomi Valkeinen Signed-off-by: Jai Luthra --- Changes from v2: - This patch was previously split for easier review, squash it now. --- drivers/media/i2c/ds90ub960.c | 848 ++++++++++++++++++++++++++++++++---------- 1 file changed, 658 insertions(+), 190 deletions(-) diff --git a/drivers/media/i2c/ds90ub960.c b/drivers/media/i2c/ds90ub960.c index 130bf4cc0a7485e997dd979954a9b6d28b693a5a..56b1a88c1c29fbefecae60f4c9976e8ede554447 100644 --- a/drivers/media/i2c/ds90ub960.c +++ b/drivers/media/i2c/ds90ub960.c @@ -243,6 +243,7 @@ #define UB960_RR_BIST_ERR_COUNT 0x57 #define UB960_RR_BCC_CONFIG 0x58 +#define UB960_RR_BCC_CONFIG_BC_ALWAYS_ON BIT(4) #define UB960_RR_BCC_CONFIG_I2C_PASS_THROUGH BIT(6) #define UB960_RR_BCC_CONFIG_BC_FREQ_SEL_MASK GENMASK(2, 0) @@ -1788,6 +1789,23 @@ static int ub960_rxport_link_ok(struct ub960_data *priv, unsigned int nport, return 0; } +static int ub960_rxport_lockup_wa_ub9702(struct ub960_data *priv) +{ + int ret; + + /* Toggle PI_MODE to avoid possible FPD RX lockup */ + + ret = ub960_update_bits(priv, UB9702_RR_CHANNEL_MODE, GENMASK(4, 3), + 2 << 3, NULL); + if (ret) + return ret; + + usleep_range(1000, 5000); + + return ub960_update_bits(priv, UB9702_RR_CHANNEL_MODE, GENMASK(4, 3), + 0, NULL); +} + /* * Wait for the RX ports to lock, have no errors and have stable strobe position * and EQ level. @@ -1818,6 +1836,7 @@ static int ub960_rxport_wait_locks(struct ub960_data *priv, link_ok_mask = 0; while (time_before(jiffies, timeout)) { + bool fpd4_wa = false; missing = 0; for_each_set_bit(nport, &port_mask, @@ -1832,6 +1851,9 @@ static int ub960_rxport_wait_locks(struct ub960_data *priv, if (ret) return ret; + if (!ok && rxport->cdr_mode == RXPORT_CDR_FPD4) + fpd4_wa = true; + /* * We want the link to be ok for two consecutive loops, * as a link could get established just before our test @@ -1851,6 +1873,12 @@ static int ub960_rxport_wait_locks(struct ub960_data *priv, if (missing == 0) break; + if (fpd4_wa) { + ret = ub960_rxport_lockup_wa_ub9702(priv); + if (ret) + return ret; + } + /* * The sleep time of 10 ms was found by testing to give a lock * with a few iterations. It can be decreased if on some setups @@ -2257,294 +2285,691 @@ static int ub960_init_rx_port_ub960(struct ub960_data *priv, return ret; } -static int ub960_init_rx_port_ub9702_fpd3(struct ub960_data *priv, - struct ub960_rxport *rxport) +static int ub960_init_rx_ports_ub960(struct ub960_data *priv) { - unsigned int nport = rxport->nport; - u8 bc_freq_val; - u8 fpd_func_mode; - int ret = 0; + struct device *dev = &priv->client->dev; + unsigned int port_lock_mask; + unsigned int port_mask; + int ret; - switch (rxport->rx_mode) { - case RXPORT_MODE_RAW10: - bc_freq_val = 0; - fpd_func_mode = 5; - break; + for_each_active_rxport(priv, it) { + ret = ub960_init_rx_port_ub960(priv, it.rxport); + if (ret) + return ret; + } - case RXPORT_MODE_RAW12_HF: - bc_freq_val = 0; - fpd_func_mode = 4; - break; + ret = ub960_reset(priv, false); + if (ret) + return ret; - case RXPORT_MODE_RAW12_LF: - bc_freq_val = 0; - fpd_func_mode = 6; - break; + port_mask = 0; - case RXPORT_MODE_CSI2_SYNC: - bc_freq_val = 6; - fpd_func_mode = 2; - break; + for_each_active_rxport(priv, it) + port_mask |= BIT(it.nport); - case RXPORT_MODE_CSI2_NONSYNC: - bc_freq_val = 2; - fpd_func_mode = 2; - break; + ret = ub960_rxport_wait_locks(priv, port_mask, &port_lock_mask); + if (ret) + return ret; - default: - return -EINVAL; + if (port_mask != port_lock_mask) { + ret = -EIO; + dev_err_probe(dev, ret, "Failed to lock all RX ports\n"); + return ret; } - ub960_rxport_update_bits(priv, nport, UB960_RR_BCC_CONFIG, 0x7, - bc_freq_val, &ret); - ub960_rxport_write(priv, nport, UB9702_RR_CHANNEL_MODE, fpd_func_mode, - &ret); + /* + * Clear any errors caused by switching the RX port settings while + * probing. + */ + ret = ub960_clear_rx_errors(priv); + if (ret) + return ret; - /* set serdes_eq_mode = 1 */ - ub960_write_ind(priv, UB960_IND_TARGET_RX_ANA(nport), 0xa8, 0x80, - &ret); + return 0; +} - /* enable serdes driver */ - ub960_write_ind(priv, UB960_IND_TARGET_RX_ANA(nport), 0x0d, 0x7f, - &ret); +/* + * UB9702 specific initial RX port configuration + */ - /* set serdes_eq_offset=4 */ - ub960_write_ind(priv, UB960_IND_TARGET_RX_ANA(nport), 0x2b, 0x04, - &ret); +static int ub960_turn_off_rxport_ub9702(struct ub960_data *priv, + unsigned int nport) +{ + int ret = 0; - /* init default serdes_eq_max in 0xa9 */ - ub960_write_ind(priv, UB960_IND_TARGET_RX_ANA(nport), 0xa9, 0x23, - &ret); + /* Disable RX port */ + ub960_update_bits(priv, UB960_SR_RX_PORT_CTL, BIT(nport), 0, &ret); + + /* Disable FPD Rx and FPD BC CMR */ + ub960_rxport_write(priv, nport, UB9702_RR_RX_CTL_2, 0x1b, &ret); + + /* Disable FPD BC Tx */ + ub960_rxport_update_bits(priv, nport, UB960_RR_BCC_CONFIG, BIT(4), 0, + &ret); + + /* Disable internal RX blocks */ + ub960_rxport_write(priv, nport, UB9702_RR_RX_CTL_1, 0x15, &ret); + + /* Disable AEQ */ + ub960_write_ind(priv, UB960_IND_TARGET_RX_ANA(nport), + UB9702_IR_RX_ANA_AEQ_CFG_2, 0x03, &ret); - /* init serdes_eq_min in 0xaa */ - ub960_write_ind(priv, UB960_IND_TARGET_RX_ANA(nport), 0xaa, 0, &ret); + /* PI disabled and oDAC disabled */ + ub960_write_ind(priv, UB960_IND_TARGET_RX_ANA(nport), + UB9702_IR_RX_ANA_AEQ_CFG_4, 0x09, &ret); - /* serdes_driver_ctl2 control: DS90UB953-Q1/DS90UB933-Q1/DS90UB913A-Q1 */ - ub960_ind_update_bits(priv, UB960_IND_TARGET_RX_ANA(nport), 0x1b, - BIT(3), BIT(3), &ret); + /* AEQ configured for disabled link */ + ub960_write_ind(priv, UB960_IND_TARGET_RX_ANA(nport), + UB9702_IR_RX_ANA_AEQ_CFG_1, 0x20, &ret); - /* RX port to half-rate */ - ub960_update_bits(priv, UB9702_SR_FPD_RATE_CFG, 0x3 << (nport * 2), - BIT(nport * 2), &ret); + /* disable AEQ clock and DFE */ + ub960_write_ind(priv, UB960_IND_TARGET_RX_ANA(nport), + UB9702_IR_RX_ANA_AEQ_CFG_3, 0x45, &ret); + + /* Powerdown FPD3 CDR */ + ub960_write_ind(priv, UB960_IND_TARGET_RX_ANA(nport), + UB9702_IR_RX_ANA_FPD3_CDR_CTRL_SEL_5, 0x82, &ret); return ret; } -static int ub960_init_rx_port_ub9702_fpd4_aeq(struct ub960_data *priv, - struct ub960_rxport *rxport) +static int ub960_set_bc_drv_config_ub9702(struct ub960_data *priv, + unsigned int nport) { - unsigned int nport = rxport->nport; - bool first_time_power_up = true; + u8 fpd_bc_ctl0; + u8 fpd_bc_ctl1; + u8 fpd_bc_ctl2; int ret = 0; - if (first_time_power_up) { - u8 v; - - /* AEQ init */ - ub960_read_ind(priv, UB960_IND_TARGET_RX_ANA(nport), 0x2c, &v, - &ret); + if (priv->rxports[nport]->cdr_mode == RXPORT_CDR_FPD4) { + /* Set FPD PBC drv into FPD IV mode */ - ub960_write_ind(priv, UB960_IND_TARGET_RX_ANA(nport), 0x27, v, - &ret); - ub960_write_ind(priv, UB960_IND_TARGET_RX_ANA(nport), 0x28, - v + 1, &ret); + fpd_bc_ctl0 = 0; + fpd_bc_ctl1 = 0; + fpd_bc_ctl2 = 0; + } else { + /* Set FPD PBC drv into FPD III mode */ - ub960_write_ind(priv, UB960_IND_TARGET_RX_ANA(nport), 0x2b, - 0x00, &ret); + fpd_bc_ctl0 = 2; + fpd_bc_ctl1 = 1; + fpd_bc_ctl2 = 5; } - /* enable serdes_eq_ctl2 */ - ub960_write_ind(priv, UB960_IND_TARGET_RX_ANA(nport), 0x9e, 0x00, - &ret); + ub960_ind_update_bits(priv, UB960_IND_TARGET_RX_ANA(nport), + UB9702_IR_RX_ANA_FPD_BC_CTL0, GENMASK(7, 5), + fpd_bc_ctl0 << 5, &ret); - /* enable serdes_eq_ctl1 */ - ub960_write_ind(priv, UB960_IND_TARGET_RX_ANA(nport), 0x90, 0x40, - &ret); + ub960_ind_update_bits(priv, UB960_IND_TARGET_RX_ANA(nport), + UB9702_IR_RX_ANA_FPD_BC_CTL1, BIT(6), + fpd_bc_ctl1 << 6, &ret); - /* enable serdes_eq_en */ - ub960_write_ind(priv, UB960_IND_TARGET_RX_ANA(nport), 0x2e, 0x40, - &ret); + ub960_ind_update_bits(priv, UB960_IND_TARGET_RX_ANA(nport), + UB9702_IR_RX_ANA_FPD_BC_CTL2, GENMASK(6, 3), + fpd_bc_ctl2 << 3, &ret); - /* disable serdes_eq_override */ - ub960_write_ind(priv, UB960_IND_TARGET_RX_ANA(nport), 0xf0, 0x00, - &ret); + return ret; +} - /* disable serdes_gain_override */ - ub960_write_ind(priv, UB960_IND_TARGET_RX_ANA(nport), 0x71, 0x00, - &ret); +static int ub960_set_fpd4_sync_mode_ub9702(struct ub960_data *priv, + unsigned int nport) +{ + int ret = 0; + + /* FPD4 Sync Mode */ + ub960_rxport_write(priv, nport, UB9702_RR_CHANNEL_MODE, 0x0, &ret); + + /* BC_FREQ_SELECT = (PLL_FREQ/3200) Mbps */ + ub960_rxport_update_bits(priv, nport, UB960_RR_BCC_CONFIG, + UB960_RR_BCC_CONFIG_BC_FREQ_SEL_MASK, 6, &ret); + + if (ret) + return ret; + + ret = ub960_set_bc_drv_config_ub9702(priv, nport); + if (ret) + return ret; + + /* Set AEQ timer to 400us/step */ + ub960_write_ind(priv, UB960_IND_TARGET_RX_ANA(nport), + UB9702_IR_RX_ANA_SYSTEM_INIT_REG0, 0x2f, &ret); + + /* Disable FPD4 Auto Recovery */ + ub960_update_bits(priv, UB9702_SR_CSI_EXCLUSIVE_FWD2, GENMASK(5, 4), 0, + &ret); + + /* Enable RX port */ + ub960_update_bits(priv, UB960_SR_RX_PORT_CTL, BIT(nport), BIT(nport), + &ret); + + /* Enable FPD4 Auto Recovery */ + ub960_update_bits(priv, UB9702_SR_CSI_EXCLUSIVE_FWD2, GENMASK(5, 4), + BIT(4), &ret); return ret; } -static int ub960_init_rx_port_ub9702_fpd4(struct ub960_data *priv, - struct ub960_rxport *rxport) +static int ub960_set_fpd4_async_mode_ub9702(struct ub960_data *priv, + unsigned int nport) { - unsigned int nport = rxport->nport; - u8 bc_freq_val; int ret = 0; - switch (rxport->rx_mode) { - case RXPORT_MODE_RAW10: - bc_freq_val = 0; - break; + /* FPD4 ASync Mode */ + ub960_rxport_write(priv, nport, UB9702_RR_CHANNEL_MODE, 0x1, &ret); - case RXPORT_MODE_RAW12_HF: - bc_freq_val = 0; - break; + /* 10Mbps w/ BC enabled */ + /* BC_FREQ_SELECT=(PLL_FREQ/3200) Mbps */ + ub960_rxport_update_bits(priv, nport, UB960_RR_BCC_CONFIG, + UB960_RR_BCC_CONFIG_BC_FREQ_SEL_MASK, 2, &ret); - case RXPORT_MODE_RAW12_LF: - bc_freq_val = 0; - break; + if (ret) + return ret; - case RXPORT_MODE_CSI2_SYNC: - bc_freq_val = 6; - break; + ret = ub960_set_bc_drv_config_ub9702(priv, nport); + if (ret) + return ret; - case RXPORT_MODE_CSI2_NONSYNC: - bc_freq_val = 2; - break; + /* Set AEQ timer to 400us/step */ + ub960_write_ind(priv, UB960_IND_TARGET_RX_ANA(nport), + UB9702_IR_RX_ANA_SYSTEM_INIT_REG0, 0x2f, &ret); - default: - return -EINVAL; - } + /* Disable FPD4 Auto Recover */ + ub960_update_bits(priv, UB9702_SR_CSI_EXCLUSIVE_FWD2, GENMASK(5, 4), 0, + &ret); - ub960_rxport_update_bits(priv, nport, UB960_RR_BCC_CONFIG, 0x7, - bc_freq_val, &ret); + /* Enable RX port */ + ub960_update_bits(priv, UB960_SR_RX_PORT_CTL, BIT(nport), BIT(nport), + &ret); - /* FPD4 Sync Mode */ - ub960_rxport_write(priv, nport, UB9702_RR_CHANNEL_MODE, 0, &ret); + /* Enable FPD4 Auto Recovery */ + ub960_update_bits(priv, UB9702_SR_CSI_EXCLUSIVE_FWD2, GENMASK(5, 4), + BIT(4), &ret); - /* add serdes_eq_offset of 4 */ - ub960_write_ind(priv, UB960_IND_TARGET_RX_ANA(nport), 0x2b, 0x04, - &ret); + return ret; +} - /* FPD4 serdes_start_eq in 0x27: assign default */ - ub960_write_ind(priv, UB960_IND_TARGET_RX_ANA(nport), 0x27, 0x0, &ret); - /* FPD4 serdes_end_eq in 0x28: assign default */ - ub960_write_ind(priv, UB960_IND_TARGET_RX_ANA(nport), 0x28, 0x23, - &ret); +static int ub960_set_fpd3_sync_mode_ub9702(struct ub960_data *priv, + unsigned int nport) +{ + int ret = 0; - /* set serdes_driver_mode into FPD IV mode */ - ub960_write_ind(priv, UB960_IND_TARGET_RX_ANA(nport), 0x04, 0x00, - &ret); - /* set FPD PBC drv into FPD IV mode */ - ub960_write_ind(priv, UB960_IND_TARGET_RX_ANA(nport), 0x1b, 0x00, - &ret); + /* FPD3 Sync Mode */ + ub960_rxport_write(priv, nport, UB9702_RR_CHANNEL_MODE, 0x2, &ret); - /* set serdes_system_init to 0x2f */ - ub960_write_ind(priv, UB960_IND_TARGET_RX_ANA(nport), 0x21, 0x2f, - &ret); - /* set serdes_system_rst in reset mode */ - ub960_write_ind(priv, UB960_IND_TARGET_RX_ANA(nport), 0x25, 0xc1, - &ret); + /* BC_FREQ_SELECT=(PLL_FREQ/3200) Mbps */ + ub960_rxport_update_bits(priv, nport, UB960_RR_BCC_CONFIG, + UB960_RR_BCC_CONFIG_BC_FREQ_SEL_MASK, 6, &ret); - /* RX port to 7.55G mode */ - ub960_update_bits(priv, UB9702_SR_FPD_RATE_CFG, 0x3 << (nport * 2), - 0 << (nport * 2), &ret); + /* Set AEQ_LOCK_MODE = 1 */ + ub960_write_ind(priv, UB960_IND_TARGET_RX_ANA(nport), + UB9702_IR_RX_ANA_FPD3_AEQ_CTRL_SEL_1, BIT(7), &ret); if (ret) return ret; - ret = ub960_init_rx_port_ub9702_fpd4_aeq(priv, rxport); + ret = ub960_set_bc_drv_config_ub9702(priv, nport); if (ret) return ret; - return 0; + /* Enable RX port */ + ub960_update_bits(priv, UB960_SR_RX_PORT_CTL, BIT(nport), BIT(nport), + &ret); + + return ret; } -static int ub960_init_rx_port_ub9702(struct ub960_data *priv, - struct ub960_rxport *rxport) +static int ub960_set_raw10_dvp_mode_ub9702(struct ub960_data *priv, + unsigned int nport) { - unsigned int nport = rxport->nport; - int ret; + int ret = 0; - if (rxport->cdr_mode == RXPORT_CDR_FPD3) - ret = ub960_init_rx_port_ub9702_fpd3(priv, rxport); - else /* RXPORT_CDR_FPD4 */ - ret = ub960_init_rx_port_ub9702_fpd4(priv, rxport); + /* FPD3 RAW10 Mode */ + ub960_rxport_write(priv, nport, UB9702_RR_CHANNEL_MODE, 0x5, &ret); + + ub960_rxport_update_bits(priv, nport, UB960_RR_BCC_CONFIG, + UB960_RR_BCC_CONFIG_BC_FREQ_SEL_MASK, 0, &ret); + + /* Set AEQ_LOCK_MODE = 1 */ + ub960_write_ind(priv, UB960_IND_TARGET_RX_ANA(nport), + UB9702_IR_RX_ANA_FPD3_AEQ_CTRL_SEL_1, BIT(7), &ret); + + /* + * RAW10_8BIT_CTL = 0b11 : 8-bit processing using lower 8 bits + * 0b10 : 8-bit processing using upper 8 bits + */ + ub960_rxport_update_bits(priv, nport, UB960_RR_PORT_CONFIG2, 0x3 << 6, + 0x2 << 6, &ret); + + /* LV_POLARITY & FV_POLARITY */ + ub960_rxport_update_bits(priv, nport, UB960_RR_PORT_CONFIG2, 0x3, + priv->rxports[nport]->lv_fv_pol, &ret); if (ret) return ret; - switch (rxport->rx_mode) { - case RXPORT_MODE_RAW10: - /* - * RAW10_8BIT_CTL = 0b11 : 8-bit processing using lower 8 bits - * 0b10 : 8-bit processing using upper 8 bits - */ - ub960_rxport_update_bits(priv, nport, UB960_RR_PORT_CONFIG2, - 0x3 << 6, 0x2 << 6, &ret); + ret = ub960_set_bc_drv_config_ub9702(priv, nport); + if (ret) + return ret; + + /* Enable RX port */ + ub960_update_bits(priv, UB960_SR_RX_PORT_CTL, BIT(nport), BIT(nport), + &ret); + + return ret; +} + +static int ub960_configure_rx_port_ub9702(struct ub960_data *priv, + unsigned int nport) +{ + struct device *dev = &priv->client->dev; + struct ub960_rxport *rxport = priv->rxports[nport]; + int ret; + + if (!rxport) { + ret = ub960_turn_off_rxport_ub9702(priv, nport); + if (ret) + return ret; + dev_dbg(dev, "rx%u: disabled\n", nport); + return 0; + } + + switch (rxport->cdr_mode) { + case RXPORT_CDR_FPD4: + switch (rxport->rx_mode) { + case RXPORT_MODE_CSI2_SYNC: + ret = ub960_set_fpd4_sync_mode_ub9702(priv, nport); + if (ret) + return ret; + + dev_dbg(dev, "rx%u: FPD-Link IV SYNC mode\n", nport); + break; + case RXPORT_MODE_CSI2_NONSYNC: + ret = ub960_set_fpd4_async_mode_ub9702(priv, nport); + if (ret) + return ret; + + dev_dbg(dev, "rx%u: FPD-Link IV ASYNC mode\n", nport); + break; + default: + dev_err(dev, "rx%u: unsupported FPD4 mode %u\n", nport, + rxport->rx_mode); + return -EINVAL; + } break; - case RXPORT_MODE_RAW12_HF: - case RXPORT_MODE_RAW12_LF: - /* Not implemented */ - return -EINVAL; + case RXPORT_CDR_FPD3: + switch (rxport->rx_mode) { + case RXPORT_MODE_CSI2_SYNC: + ret = ub960_set_fpd3_sync_mode_ub9702(priv, nport); + if (ret) + return ret; - case RXPORT_MODE_CSI2_SYNC: - case RXPORT_MODE_CSI2_NONSYNC: + dev_dbg(dev, "rx%u: FPD-Link III SYNC mode\n", nport); + break; + case RXPORT_MODE_RAW10: + ret = ub960_set_raw10_dvp_mode_ub9702(priv, nport); + if (ret) + return ret; + dev_dbg(dev, "rx%u: FPD-Link III RAW10 DVP mode\n", + nport); + break; + default: + dev_err(&priv->client->dev, + "rx%u: unsupported FPD3 mode %u\n", nport, + rxport->rx_mode); + return -EINVAL; + } break; + + default: + dev_err(&priv->client->dev, "rx%u: unsupported CDR mode %u\n", + nport, rxport->cdr_mode); + return -EINVAL; } - /* LV_POLARITY & FV_POLARITY */ - ub960_rxport_update_bits(priv, nport, UB960_RR_PORT_CONFIG2, 0x3, - rxport->lv_fv_pol, &ret); + return 0; +} - /* Enable all interrupt sources from this port */ - ub960_rxport_write(priv, nport, UB960_RR_PORT_ICR_HI, 0x07, &ret); - ub960_rxport_write(priv, nport, UB960_RR_PORT_ICR_LO, 0x7f, &ret); +static int ub960_lock_recovery_ub9702(struct ub960_data *priv, + unsigned int nport) +{ + struct device *dev = &priv->client->dev; + /* Assumption that max AEQ should be under 16 */ + const u8 rx_aeq_limit = 16; + u8 prev_aeq = 0xff; + bool rx_lock; + + for (unsigned int retry = 0; retry < 3; ++retry) { + u8 port_sts1; + u8 rx_aeq; + int ret; - /* Enable I2C_PASS_THROUGH */ - ub960_rxport_update_bits(priv, nport, UB960_RR_BCC_CONFIG, - UB960_RR_BCC_CONFIG_I2C_PASS_THROUGH, - UB960_RR_BCC_CONFIG_I2C_PASS_THROUGH, &ret); + ret = ub960_rxport_read(priv, nport, UB960_RR_RX_PORT_STS1, + &port_sts1, NULL); + if (ret) + return ret; - /* Enable I2C communication to the serializer via the alias addr */ - ub960_rxport_write(priv, nport, UB960_RR_SER_ALIAS_ID, - rxport->ser.alias << 1, &ret); + rx_lock = port_sts1 & UB960_RR_RX_PORT_STS1_PORT_PASS; - /* Enable RX port */ - ub960_update_bits(priv, UB960_SR_RX_PORT_CTL, BIT(nport), BIT(nport), - &ret); + if (!rx_lock) { + ret = ub960_rxport_lockup_wa_ub9702(priv); + if (ret) + return ret; + + /* Restart AEQ by changing max to 0 --> 0x23 */ + ret = ub960_write_ind(priv, + UB960_IND_TARGET_RX_ANA(nport), + UB9702_IR_RX_ANA_AEQ_ALP_SEL7, 0, + NULL); + if (ret) + return ret; + + msleep(20); + + /* AEQ Restart */ + ret = ub960_write_ind(priv, + UB960_IND_TARGET_RX_ANA(nport), + UB9702_IR_RX_ANA_AEQ_ALP_SEL7, + 0x23, NULL); + + if (ret) + return ret; - if (rxport->cdr_mode == RXPORT_CDR_FPD4) { - /* unreset 960 AEQ */ - ub960_write_ind(priv, UB960_IND_TARGET_RX_ANA(nport), 0x25, - 0x41, &ret); + msleep(20); + dev_dbg(dev, "rx%u: no lock, retry = %u\n", nport, + retry); + + continue; + } + + ret = ub960_read_ind(priv, UB960_IND_TARGET_RX_ANA(nport), + UB9702_IR_RX_ANA_AEQ_ALP_SEL11, &rx_aeq, + NULL); + if (ret) + return ret; + + if (rx_aeq < rx_aeq_limit) { + dev_dbg(dev, + "rx%u: locked and AEQ normal before setting AEQ window\n", + nport); + return 0; + } + + if (rx_aeq != prev_aeq) { + ret = ub960_rxport_lockup_wa_ub9702(priv); + if (ret) + return ret; + + /* Restart AEQ by changing max to 0 --> 0x23 */ + ret = ub960_write_ind(priv, + UB960_IND_TARGET_RX_ANA(nport), + UB9702_IR_RX_ANA_AEQ_ALP_SEL7, + 0, NULL); + if (ret) + return ret; + + msleep(20); + + /* AEQ Restart */ + ret = ub960_write_ind(priv, + UB960_IND_TARGET_RX_ANA(nport), + UB9702_IR_RX_ANA_AEQ_ALP_SEL7, + 0x23, NULL); + if (ret) + return ret; + + msleep(20); + + dev_dbg(dev, + "rx%u: high AEQ at initial check recovery loop, retry=%u\n", + nport, retry); + + prev_aeq = rx_aeq; + } else { + dev_dbg(dev, + "rx%u: lossy cable detected, RX_AEQ %#x, RX_AEQ_LIMIT %#x, retry %u\n", + nport, rx_aeq, rx_aeq_limit, retry); + dev_dbg(dev, + "rx%u: will continue with initiation sequence but high AEQ\n", + nport); + return 0; + } } - return ret; + dev_err(dev, "rx%u: max number of retries: %s\n", nport, + rx_lock ? "unstable AEQ" : "no lock"); + + return -EIO; } -static int ub960_init_rx_ports(struct ub960_data *priv) +static int ub960_enable_aeq_lms_ub9702(struct ub960_data *priv, + unsigned int nport) +{ + struct device *dev = &priv->client->dev; + u8 read_aeq_init; + int ret; + + ret = ub960_read_ind(priv, UB960_IND_TARGET_RX_ANA(nport), + UB9702_IR_RX_ANA_AEQ_ALP_SEL11, &read_aeq_init, + NULL); + if (ret) + return ret; + + dev_dbg(dev, "rx%u: initial AEQ = %#x\n", nport, read_aeq_init); + + /* Set AEQ Min */ + ub960_write_ind(priv, UB960_IND_TARGET_RX_ANA(nport), + UB9702_IR_RX_ANA_AEQ_ALP_SEL6, read_aeq_init, &ret); + /* Set AEQ Max */ + ub960_write_ind(priv, UB960_IND_TARGET_RX_ANA(nport), + UB9702_IR_RX_ANA_AEQ_ALP_SEL7, read_aeq_init + 1, &ret); + /* Set AEQ offset to 0 */ + ub960_write_ind(priv, UB960_IND_TARGET_RX_ANA(nport), + UB9702_IR_RX_ANA_AEQ_ALP_SEL10, 0x0, &ret); + + /* Enable AEQ tap2 */ + ub960_write_ind(priv, UB960_IND_TARGET_RX_ANA(nport), + UB9702_IR_RX_ANA_EQ_CTRL_SEL_38, 0x00, &ret); + /* Set VGA Gain 1 Gain 2 override to 0 */ + ub960_write_ind(priv, UB960_IND_TARGET_RX_ANA(nport), + UB9702_IR_RX_ANA_VGA_CTRL_SEL_8, 0x00, &ret); + /* Set VGA Initial Sweep Gain to 0 */ + ub960_write_ind(priv, UB960_IND_TARGET_RX_ANA(nport), + UB9702_IR_RX_ANA_VGA_CTRL_SEL_6, 0x80, &ret); + /* Set VGA_Adapt (VGA Gain) override to 0 (thermometer encoded) */ + ub960_write_ind(priv, UB960_IND_TARGET_RX_ANA(nport), + UB9702_IR_RX_ANA_VGA_CTRL_SEL_3, 0x00, &ret); + /* Enable VGA_SWEEP */ + ub960_write_ind(priv, UB960_IND_TARGET_RX_ANA(nport), + UB9702_IR_RX_ANA_EQ_ADAPT_CTRL, 0x40, &ret); + /* Disable VGA_SWEEP_GAIN_OV, disable VGA_TUNE_OV */ + ub960_write_ind(priv, UB960_IND_TARGET_RX_ANA(nport), + UB9702_IR_RX_ANA_EQ_OVERRIDE_CTRL, 0x00, &ret); + + /* Set VGA HIGH Threshold to 43 */ + ub960_write_ind(priv, UB960_IND_TARGET_RX_ANA(nport), + UB9702_IR_RX_ANA_VGA_CTRL_SEL_1, 0x2b, &ret); + /* Set VGA LOW Threshold to 18 */ + ub960_write_ind(priv, UB960_IND_TARGET_RX_ANA(nport), + UB9702_IR_RX_ANA_VGA_CTRL_SEL_2, 0x12, &ret); + /* Set vga_sweep_th to 32 */ + ub960_write_ind(priv, UB960_IND_TARGET_RX_ANA(nport), + UB9702_IR_RX_ANA_EQ_CTRL_SEL_15, 0x20, &ret); + /* Set AEQ timer to 400us/step and parity threshold to 7 */ + ub960_write_ind(priv, UB960_IND_TARGET_RX_ANA(nport), + UB9702_IR_RX_ANA_SYSTEM_INIT_REG0, 0xef, &ret); + + if (ret) + return ret; + + dev_dbg(dev, "rx%u: enable FPD-Link IV AEQ LMS\n", nport); + + return 0; +} + +static int ub960_enable_dfe_lms_ub9702(struct ub960_data *priv, + unsigned int nport) +{ + struct device *dev = &priv->client->dev; + int ret = 0; + + /* Enable DFE LMS */ + ub960_write_ind(priv, UB960_IND_TARGET_RX_ANA(nport), + UB9702_IR_RX_ANA_EQ_CTRL_SEL_24, 0x40, &ret); + /* Disable VGA Gain1 override */ + ub960_write_ind(priv, UB960_IND_TARGET_RX_ANA(nport), + UB9702_IR_RX_ANA_GAIN_CTRL_0, 0x20, &ret); + + if (ret) + return ret; + + usleep_range(1000, 5000); + + /* Disable VGA Gain2 override */ + ret = ub960_write_ind(priv, UB960_IND_TARGET_RX_ANA(nport), + UB9702_IR_RX_ANA_GAIN_CTRL_0, 0x00, NULL); + if (ret) + return ret; + + dev_dbg(dev, "rx%u: enabled FPD-Link IV DFE LMS", nport); + + return 0; +} + +static int ub960_init_rx_ports_ub9702(struct ub960_data *priv) { struct device *dev = &priv->client->dev; unsigned int port_lock_mask; - unsigned int port_mask; + unsigned int port_mask = 0; + bool have_fpd4 = false; int ret; for_each_active_rxport(priv, it) { - int ret; + ret = ub960_rxport_update_bits(priv, it.nport, + UB960_RR_BCC_CONFIG, + UB960_RR_BCC_CONFIG_BC_ALWAYS_ON, + UB960_RR_BCC_CONFIG_BC_ALWAYS_ON, + NULL); + if (ret) + return ret; + } - if (priv->hw_data->is_ub9702) - ret = ub960_init_rx_port_ub9702(priv, it.rxport); - else - ret = ub960_init_rx_port_ub960(priv, it.rxport); + /* Disable FPD4 Auto Recovery */ + ret = ub960_write(priv, UB9702_SR_CSI_EXCLUSIVE_FWD2, 0x0f, NULL); + if (ret) + return ret; + + for_each_active_rxport_fpd4(priv, it) { + /* Hold state machine in reset */ + ub960_rxport_write(priv, it.nport, UB9702_RR_RX_SM_SEL_2, 0x10, + &ret); + + /* Set AEQ max to 0 */ + ub960_write_ind(priv, UB960_IND_TARGET_RX_ANA(it.nport), + UB9702_IR_RX_ANA_AEQ_ALP_SEL7, 0, &ret); if (ret) return ret; + + dev_dbg(dev, + "rx%u: holding state machine and adjusting AEQ max to 0", + it.nport); + } + + for_each_active_rxport(priv, it) { + port_mask |= BIT(it.nport); + + if (it.rxport->cdr_mode == RXPORT_CDR_FPD4) + have_fpd4 = true; + } + + for_each_rxport(priv, it) { + ret = ub960_configure_rx_port_ub9702(priv, it.nport); + if (ret) + return ret; } ret = ub960_reset(priv, false); if (ret) return ret; - port_mask = 0; + if (have_fpd4) { + for_each_active_rxport_fpd4(priv, it) { + /* Release state machine */ + ret = ub960_rxport_write(priv, it.nport, + UB9702_RR_RX_SM_SEL_2, 0x0, + NULL); + if (ret) + return ret; - for_each_active_rxport(priv, it) - port_mask |= BIT(it.nport); + dev_dbg(dev, "rx%u: state machine released\n", + it.nport); + } + + /* Wait for SM to resume */ + fsleep(5000); + + for_each_active_rxport_fpd4(priv, it) { + ret = ub960_write_ind(priv, + UB960_IND_TARGET_RX_ANA(it.nport), + UB9702_IR_RX_ANA_AEQ_ALP_SEL7, + 0x23, NULL); + if (ret) + return ret; + + dev_dbg(dev, "rx%u: AEQ restart\n", it.nport); + } + + /* Wait for lock */ + fsleep(20000); + + for_each_active_rxport_fpd4(priv, it) { + ret = ub960_lock_recovery_ub9702(priv, it.nport); + if (ret) + return ret; + } + + for_each_active_rxport_fpd4(priv, it) { + ret = ub960_enable_aeq_lms_ub9702(priv, it.nport); + if (ret) + return ret; + } + + for_each_active_rxport_fpd4(priv, it) { + /* Hold state machine in reset */ + ret = ub960_rxport_write(priv, it.nport, + UB9702_RR_RX_SM_SEL_2, 0x10, + NULL); + if (ret) + return ret; + } + + ret = ub960_reset(priv, false); + if (ret) + return ret; + + for_each_active_rxport_fpd4(priv, it) { + /* Release state machine */ + ret = ub960_rxport_write(priv, it.nport, + UB9702_RR_RX_SM_SEL_2, 0, + NULL); + if (ret) + return ret; + } + } + + /* Wait time for stable lock */ + fsleep(15000); + + for_each_active_rxport_fpd4(priv, it) { + ret = ub960_enable_dfe_lms_ub9702(priv, it.nport); + if (ret) + return ret; + } + + /* Wait for DFE and LMS to adapt */ + fsleep(5000); ret = ub960_rxport_wait_locks(priv, port_mask, &port_lock_mask); if (ret) @@ -2556,10 +2981,49 @@ static int ub960_init_rx_ports(struct ub960_data *priv) return ret; } + for_each_active_rxport(priv, it) { + /* Enable all interrupt sources from this port */ + ub960_rxport_write(priv, it.nport, UB960_RR_PORT_ICR_HI, 0x07, + &ret); + ub960_rxport_write(priv, it.nport, UB960_RR_PORT_ICR_LO, 0x7f, + &ret); + + /* Enable I2C_PASS_THROUGH */ + ub960_rxport_update_bits(priv, it.nport, UB960_RR_BCC_CONFIG, + UB960_RR_BCC_CONFIG_I2C_PASS_THROUGH, + UB960_RR_BCC_CONFIG_I2C_PASS_THROUGH, + &ret); + + /* Enable I2C communication to the serializer via the alias */ + ub960_rxport_write(priv, it.nport, UB960_RR_SER_ALIAS_ID, + it.rxport->ser.alias << 1, &ret); + + if (ret) + return ret; + } + + /* Enable FPD4 Auto Recovery, Recovery loop active */ + ret = ub960_write(priv, UB9702_SR_CSI_EXCLUSIVE_FWD2, 0x18, NULL); + if (ret) + return ret; + + for_each_active_rxport_fpd4(priv, it) { + u8 final_aeq; + + ret = ub960_read_ind(priv, UB960_IND_TARGET_RX_ANA(it.nport), + UB9702_IR_RX_ANA_AEQ_ALP_SEL11, &final_aeq, + NULL); + if (ret) + return ret; + + dev_dbg(dev, "rx%u: final AEQ = %#x\n", it.nport, final_aeq); + } + /* * Clear any errors caused by switching the RX port settings while * probing. */ + ret = ub960_clear_rx_errors(priv); if (ret) return ret; @@ -4393,7 +4857,11 @@ static int ub960_probe(struct i2c_client *client) if (ret) goto err_free_ports; - ret = ub960_init_rx_ports(priv); + if (priv->hw_data->is_ub9702) + ret = ub960_init_rx_ports_ub9702(priv); + else + ret = ub960_init_rx_ports_ub960(priv); + if (ret) goto err_disable_vpocs; From patchwork Mon Mar 3 16:02:20 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jai Luthra X-Patchwork-Id: 870013 Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E4542218851; Mon, 3 Mar 2025 16:03:48 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=213.167.242.64 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741017830; cv=none; b=OtCdAJyOttwgx9NhZVXupxJ81jX6xDHlKfkdmumR4TQkG6ofiIfTGA8RL+6DvqKMXJLq7MoGdRIIcRCLjXEj8tfPMTU3PKzS03n+CF/g37VFjae/kc+5gYvZ8bSy7846SuMAOmZthuzCpkXEjldn/jguy27NGxe+erPdTnC+y1g= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741017830; c=relaxed/simple; bh=zZPbJRVbcv3vSObeofkVZ/Xpu8cPwCJC/Sr7IjprMaY=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=HzYCtighIarjem3YlPz5tgCU75fhrZRa/WJXveEKvEO3uLDjsOT92PA6FWZXn1DsdWWzaE55D+Ruj+scT6TsT6596WeDCNySvJ3044LRsCbjz+C70g7dCHV53IfMiGtxnIa1HsDwQrCAojv1buQ+B7QiL271U0rFuKIk51PYlmc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=ideasonboard.com; spf=pass smtp.mailfrom=ideasonboard.com; dkim=pass (1024-bit key) header.d=ideasonboard.com header.i=@ideasonboard.com header.b=cp6NskWy; arc=none smtp.client-ip=213.167.242.64 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=ideasonboard.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=ideasonboard.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="cp6NskWy" Received: from mail.ideasonboard.com (unknown [IPv6:2401:4900:1c69:8872:6fe4:6987:313:70cc]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id D4FF822A; Mon, 3 Mar 2025 17:02:15 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1741017736; bh=zZPbJRVbcv3vSObeofkVZ/Xpu8cPwCJC/Sr7IjprMaY=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=cp6NskWyzosAENt6Nv9ZT/HxRWWqCdzL0fizFndoGPqa2vmMpRG0hap+wOy9JWGiK U7rYxi5ee5Gu/43ZeJfPvoR/ctxVOBRC2OrSvxXoWy8oe5lLsjyu/H6CIwsxVeXZCM O4yqGXrlYQWY9X391vR+EJ7zLb15ND5zBOmjknV8= From: Jai Luthra Date: Mon, 03 Mar 2025 21:32:20 +0530 Subject: [PATCH v3 17/19] media: i2c: ds90ub953: Move reg defines to a header file Precedence: bulk X-Mailing-List: linux-media@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20250303-b4-ub9xx-err-handling-v3-17-7d178796a2b9@ideasonboard.com> References: <20250303-b4-ub9xx-err-handling-v3-0-7d178796a2b9@ideasonboard.com> In-Reply-To: <20250303-b4-ub9xx-err-handling-v3-0-7d178796a2b9@ideasonboard.com> To: Mauro Carvalho Chehab , Sakari Ailus Cc: Tomi Valkeinen , Devarsh Thakkar , linux-media@vger.kernel.org, linux-kernel@vger.kernel.org, stable@vger.kernel.org, Jai Luthra X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=7898; i=jai.luthra@ideasonboard.com; h=from:subject:message-id; bh=4hyGHzLF7tBxcUAYN2w6HvfNNMkRys4uf6IgSl7J+9w=; b=owEBbQKS/ZANAwAIAUPekfkkmnFFAcsmYgBnxdKAJSKGx8opZc0uDkQQbykpYCB+qfBO9wf57 FVNX+tt0J6JAjMEAAEIAB0WIQRN4NgY5dV16NRar8VD3pH5JJpxRQUCZ8XSgAAKCRBD3pH5JJpx RUjNEACmSH6KZ0/C90uPfGGSjBgJj3sqdrVZ44NjYLWk+nTMkS1w1BUKiu3+iSda9seru5RNhiD X5JejmfinfDUcI7BdHGzAPSozUR/wzdsetSxHLHFNjBbIu+ogrIW3mujpKN6pF/bf9fC1I1/rBa cCesNzIzCOAmSLqVoBN/o0adQ2hB08lO7jRWmTIQMQl5BY65XCA/WaFQQ9bP4vzFanOtgKIVti6 j+q9hG+kQiWAtWBf3U5O9FUJ0NeO2NwYUNHiybeOjb1hl8w0uBr9WZyly+cqOVrrq951dHlPfZt i3OG3GWzU0RYSD5sP0x8lheNaxgQEWkwcNndxkkVw7g4q0OB5eqBp7gOT8vApys9R91YlPYyRK2 2oJeUUWk5a9QUj6d+JsBJoXW2t90d1Vght/uRFowdZbGOXPcxvmCefkU/OMsfsp6kE7ZfElET3D X1bckwYQwlqphn/hxQ/Tt1+0QR/H3yi+6ra4gjGTr/OiFQFGi4R1oJPtbuX+DQpJNUcVhC7yyLZ k3/wqezJsWqkV4zTZyg2ghpYf7YwNxZ621jDDmlF4DliBFNlctQzHv/dQx45E9wo9BhNfh1jY0k ZuvzbSgk07mxcE0roJm1sg1U76aGYCMYLQvWtnrlpKdk67S81l1UE+Y5I0Vi+xx40I9AYkHHJJe uIwsjoj7Wj0HPkg== X-Developer-Key: i=jai.luthra@ideasonboard.com; a=openpgp; fpr=4DE0D818E5D575E8D45AAFC543DE91F9249A7145 From: Tomi Valkeinen Move UB953 register defines to a header file. This is done so that the deserializer driver can access the defines, and do some early serializer configuration. Signed-off-by: Tomi Valkeinen Signed-off-by: Jai Luthra --- drivers/media/i2c/ds90ub953.c | 89 +--------------------------------------- drivers/media/i2c/ds90ub953.h | 95 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 97 insertions(+), 87 deletions(-) diff --git a/drivers/media/i2c/ds90ub953.c b/drivers/media/i2c/ds90ub953.c index a5c23e94f4eab5896a2114cfdf2e5f68cde77568..c305b4e03e07798b6526ff2423811f3f7d5bdac8 100644 --- a/drivers/media/i2c/ds90ub953.c +++ b/drivers/media/i2c/ds90ub953.c @@ -28,6 +28,8 @@ #include #include +#include "ds90ub953.h" + #define UB953_PAD_SINK 0 #define UB953_PAD_SOURCE 1 @@ -35,93 +37,6 @@ #define UB953_DEFAULT_CLKOUT_RATE 25000000UL -#define UB953_REG_RESET_CTL 0x01 -#define UB953_REG_RESET_CTL_DIGITAL_RESET_1 BIT(1) -#define UB953_REG_RESET_CTL_DIGITAL_RESET_0 BIT(0) - -#define UB953_REG_GENERAL_CFG 0x02 -#define UB953_REG_GENERAL_CFG_CONT_CLK BIT(6) -#define UB953_REG_GENERAL_CFG_CSI_LANE_SEL_SHIFT 4 -#define UB953_REG_GENERAL_CFG_CSI_LANE_SEL_MASK GENMASK(5, 4) -#define UB953_REG_GENERAL_CFG_CRC_TX_GEN_ENABLE BIT(1) -#define UB953_REG_GENERAL_CFG_I2C_STRAP_MODE BIT(0) - -#define UB953_REG_MODE_SEL 0x03 -#define UB953_REG_MODE_SEL_MODE_DONE BIT(3) -#define UB953_REG_MODE_SEL_MODE_OVERRIDE BIT(4) -#define UB953_REG_MODE_SEL_MODE_MASK GENMASK(2, 0) - -#define UB953_REG_CLKOUT_CTRL0 0x06 -#define UB953_REG_CLKOUT_CTRL1 0x07 - -#define UB953_REG_I2C_CONTROL2 0x0a -#define UB953_REG_I2C_CONTROL2_SDA_OUTPUT_SETUP_SHIFT 4 -#define UB953_REG_I2C_CONTROL2_BUS_SPEEDUP BIT(1) - -#define UB953_REG_SCL_HIGH_TIME 0x0b -#define UB953_REG_SCL_LOW_TIME 0x0c - -#define UB953_REG_LOCAL_GPIO_DATA 0x0d -#define UB953_REG_LOCAL_GPIO_DATA_GPIO_RMTEN(n) BIT(4 + (n)) -#define UB953_REG_LOCAL_GPIO_DATA_GPIO_OUT_SRC(n) BIT(0 + (n)) - -#define UB953_REG_GPIO_INPUT_CTRL 0x0e -#define UB953_REG_GPIO_INPUT_CTRL_OUT_EN(n) BIT(4 + (n)) -#define UB953_REG_GPIO_INPUT_CTRL_INPUT_EN(n) BIT(0 + (n)) - -#define UB953_REG_BC_CTRL 0x49 -#define UB953_REG_BC_CTRL_CRC_ERR_CLR BIT(3) - -#define UB953_REG_REV_MASK_ID 0x50 -#define UB953_REG_GENERAL_STATUS 0x52 - -#define UB953_REG_GPIO_PIN_STS 0x53 -#define UB953_REG_GPIO_PIN_STS_GPIO_STS(n) BIT(0 + (n)) - -#define UB953_REG_BIST_ERR_CNT 0x54 -#define UB953_REG_CRC_ERR_CNT1 0x55 -#define UB953_REG_CRC_ERR_CNT2 0x56 - -#define UB953_REG_CSI_ERR_CNT 0x5c -#define UB953_REG_CSI_ERR_STATUS 0x5d -#define UB953_REG_CSI_ERR_DLANE01 0x5e -#define UB953_REG_CSI_ERR_DLANE23 0x5f -#define UB953_REG_CSI_ERR_CLK_LANE 0x60 -#define UB953_REG_CSI_PKT_HDR_VC_ID 0x61 -#define UB953_REG_PKT_HDR_WC_LSB 0x62 -#define UB953_REG_PKT_HDR_WC_MSB 0x63 -#define UB953_REG_CSI_ECC 0x64 - -#define UB953_REG_IND_ACC_CTL 0xb0 -#define UB953_REG_IND_ACC_ADDR 0xb1 -#define UB953_REG_IND_ACC_DATA 0xb2 - -#define UB953_REG_FPD3_RX_ID(n) (0xf0 + (n)) -#define UB953_REG_FPD3_RX_ID_LEN 6 - -/* Indirect register blocks */ -#define UB953_IND_TARGET_PAT_GEN 0x00 -#define UB953_IND_TARGET_FPD3_TX 0x01 -#define UB953_IND_TARGET_DIE_ID 0x02 - -#define UB953_IND_PGEN_CTL 0x01 -#define UB953_IND_PGEN_CTL_PGEN_ENABLE BIT(0) -#define UB953_IND_PGEN_CFG 0x02 -#define UB953_IND_PGEN_CSI_DI 0x03 -#define UB953_IND_PGEN_LINE_SIZE1 0x04 -#define UB953_IND_PGEN_LINE_SIZE0 0x05 -#define UB953_IND_PGEN_BAR_SIZE1 0x06 -#define UB953_IND_PGEN_BAR_SIZE0 0x07 -#define UB953_IND_PGEN_ACT_LPF1 0x08 -#define UB953_IND_PGEN_ACT_LPF0 0x09 -#define UB953_IND_PGEN_TOT_LPF1 0x0a -#define UB953_IND_PGEN_TOT_LPF0 0x0b -#define UB953_IND_PGEN_LINE_PD1 0x0c -#define UB953_IND_PGEN_LINE_PD0 0x0d -#define UB953_IND_PGEN_VBP 0x0e -#define UB953_IND_PGEN_VFP 0x0f -#define UB953_IND_PGEN_COLOR(n) (0x10 + (n)) /* n <= 15 */ - /* Note: Only sync mode supported for now */ enum ub953_mode { /* FPD-Link III CSI-2 synchronous mode */ diff --git a/drivers/media/i2c/ds90ub953.h b/drivers/media/i2c/ds90ub953.h new file mode 100644 index 0000000000000000000000000000000000000000..8bb28f0daee96044a7bf838a680e506af4f70f10 --- /dev/null +++ b/drivers/media/i2c/ds90ub953.h @@ -0,0 +1,95 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifndef __MEDIA_I2C_DS90UB953_H__ +#define __MEDIA_I2C_DS90UB953_H__ + +#include + +#define UB953_REG_RESET_CTL 0x01 +#define UB953_REG_RESET_CTL_DIGITAL_RESET_1 BIT(1) +#define UB953_REG_RESET_CTL_DIGITAL_RESET_0 BIT(0) + +#define UB953_REG_GENERAL_CFG 0x02 +#define UB953_REG_GENERAL_CFG_CONT_CLK BIT(6) +#define UB953_REG_GENERAL_CFG_CSI_LANE_SEL_SHIFT 4 +#define UB953_REG_GENERAL_CFG_CSI_LANE_SEL_MASK GENMASK(5, 4) +#define UB953_REG_GENERAL_CFG_CRC_TX_GEN_ENABLE BIT(1) +#define UB953_REG_GENERAL_CFG_I2C_STRAP_MODE BIT(0) + +#define UB953_REG_MODE_SEL 0x03 +#define UB953_REG_MODE_SEL_MODE_DONE BIT(3) +#define UB953_REG_MODE_SEL_MODE_OVERRIDE BIT(4) +#define UB953_REG_MODE_SEL_MODE_MASK GENMASK(2, 0) + +#define UB953_REG_CLKOUT_CTRL0 0x06 +#define UB953_REG_CLKOUT_CTRL1 0x07 + +#define UB953_REG_I2C_CONTROL2 0x0a +#define UB953_REG_I2C_CONTROL2_SDA_OUTPUT_SETUP_SHIFT 4 +#define UB953_REG_I2C_CONTROL2_BUS_SPEEDUP BIT(1) + +#define UB953_REG_SCL_HIGH_TIME 0x0b +#define UB953_REG_SCL_LOW_TIME 0x0c + +#define UB953_REG_LOCAL_GPIO_DATA 0x0d +#define UB953_REG_LOCAL_GPIO_DATA_GPIO_RMTEN(n) BIT(4 + (n)) +#define UB953_REG_LOCAL_GPIO_DATA_GPIO_OUT_SRC(n) BIT(0 + (n)) + +#define UB953_REG_GPIO_INPUT_CTRL 0x0e +#define UB953_REG_GPIO_INPUT_CTRL_OUT_EN(n) BIT(4 + (n)) +#define UB953_REG_GPIO_INPUT_CTRL_INPUT_EN(n) BIT(0 + (n)) + +#define UB953_REG_BC_CTRL 0x49 +#define UB953_REG_BC_CTRL_CRC_ERR_CLR BIT(3) + +#define UB953_REG_REV_MASK_ID 0x50 +#define UB953_REG_GENERAL_STATUS 0x52 + +#define UB953_REG_GPIO_PIN_STS 0x53 +#define UB953_REG_GPIO_PIN_STS_GPIO_STS(n) BIT(0 + (n)) + +#define UB953_REG_BIST_ERR_CNT 0x54 +#define UB953_REG_CRC_ERR_CNT1 0x55 +#define UB953_REG_CRC_ERR_CNT2 0x56 + +#define UB953_REG_CSI_ERR_CNT 0x5c +#define UB953_REG_CSI_ERR_STATUS 0x5d +#define UB953_REG_CSI_ERR_DLANE01 0x5e +#define UB953_REG_CSI_ERR_DLANE23 0x5f +#define UB953_REG_CSI_ERR_CLK_LANE 0x60 +#define UB953_REG_CSI_PKT_HDR_VC_ID 0x61 +#define UB953_REG_PKT_HDR_WC_LSB 0x62 +#define UB953_REG_PKT_HDR_WC_MSB 0x63 +#define UB953_REG_CSI_ECC 0x64 + +#define UB953_REG_IND_ACC_CTL 0xb0 +#define UB953_REG_IND_ACC_ADDR 0xb1 +#define UB953_REG_IND_ACC_DATA 0xb2 + +#define UB953_REG_FPD3_RX_ID(n) (0xf0 + (n)) +#define UB953_REG_FPD3_RX_ID_LEN 6 + +/* Indirect register blocks */ +#define UB953_IND_TARGET_PAT_GEN 0x00 +#define UB953_IND_TARGET_FPD3_TX 0x01 +#define UB953_IND_TARGET_DIE_ID 0x02 + +#define UB953_IND_PGEN_CTL 0x01 +#define UB953_IND_PGEN_CTL_PGEN_ENABLE BIT(0) +#define UB953_IND_PGEN_CFG 0x02 +#define UB953_IND_PGEN_CSI_DI 0x03 +#define UB953_IND_PGEN_LINE_SIZE1 0x04 +#define UB953_IND_PGEN_LINE_SIZE0 0x05 +#define UB953_IND_PGEN_BAR_SIZE1 0x06 +#define UB953_IND_PGEN_BAR_SIZE0 0x07 +#define UB953_IND_PGEN_ACT_LPF1 0x08 +#define UB953_IND_PGEN_ACT_LPF0 0x09 +#define UB953_IND_PGEN_TOT_LPF1 0x0a +#define UB953_IND_PGEN_TOT_LPF0 0x0b +#define UB953_IND_PGEN_LINE_PD1 0x0c +#define UB953_IND_PGEN_LINE_PD0 0x0d +#define UB953_IND_PGEN_VBP 0x0e +#define UB953_IND_PGEN_VFP 0x0f +#define UB953_IND_PGEN_COLOR(n) (0x10 + (n)) /* n <= 15 */ + +#endif /* __MEDIA_I2C_DS90UB953_H__ */ From patchwork Mon Mar 3 16:02:22 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jai Luthra X-Patchwork-Id: 870012 Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0549F21B9E9; Mon, 3 Mar 2025 16:03:59 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=213.167.242.64 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741017841; cv=none; b=QgjBKzWvCum/GZpNDBMP/O5tcIz3S/hM8xX1AUJSDGopMTk5YC15V9Pd96gF0YvnN55sv1zC/gLyDOEEM7HauellKOO6gco4vMJbkuWckXynN0BygFF0Uq40kqu/ftQFjjfKTAkxoV2kRiuw86vydfbPVFRUo5j5a9wYmMAlvu4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741017841; c=relaxed/simple; bh=g+H/ekm4a1tNd9/uuqmtmBcE1liUdfh8+ZrY8uuygvc=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Px8Y5AWcCrpvKEloNjEjAFgY7o1oR4Bji4n4612iZYmU/D70vsJC4ZIC5qjBt87zco4AtIfq10NerXPTd+TJ8OWMY8nFmJbtve8Um/a+ZQyyR4dWMNG8AFa/dTe0KLZuTtLrLPNegV5X+7CLwTKbP70USnwleyLtdK1oy/Okd/s= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=ideasonboard.com; spf=pass smtp.mailfrom=ideasonboard.com; dkim=pass (1024-bit key) header.d=ideasonboard.com header.i=@ideasonboard.com header.b=e0hPPRS+; arc=none smtp.client-ip=213.167.242.64 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=ideasonboard.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=ideasonboard.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="e0hPPRS+" Received: from mail.ideasonboard.com (unknown [IPv6:2401:4900:1c69:8872:6fe4:6987:313:70cc]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 016A822A; Mon, 3 Mar 2025 17:02:26 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1741017747; bh=g+H/ekm4a1tNd9/uuqmtmBcE1liUdfh8+ZrY8uuygvc=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=e0hPPRS+27gKnKXtQUHFEwz0AB2UQ/QtoE5PXCtdmaTaNqcB7jmRNpBCrRGHxdMim K8XokO9qyEVVZAXkF0osidbf9Ns7oJbpI9xThZiTydW/9NFar1s3X7vZfPcvzWXbq3 HOu3cJoklc5T+wE6G2KPrwLjX1J8WczjQbMzjVBY= From: Jai Luthra Date: Mon, 03 Mar 2025 21:32:22 +0530 Subject: [PATCH v3 19/19] media: i2c: ds90ub9xx: Set serializer temperature ramp Precedence: bulk X-Mailing-List: linux-media@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20250303-b4-ub9xx-err-handling-v3-19-7d178796a2b9@ideasonboard.com> References: <20250303-b4-ub9xx-err-handling-v3-0-7d178796a2b9@ideasonboard.com> In-Reply-To: <20250303-b4-ub9xx-err-handling-v3-0-7d178796a2b9@ideasonboard.com> To: Mauro Carvalho Chehab , Sakari Ailus Cc: Tomi Valkeinen , Devarsh Thakkar , linux-media@vger.kernel.org, linux-kernel@vger.kernel.org, stable@vger.kernel.org, Jai Luthra X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=6487; i=jai.luthra@ideasonboard.com; h=from:subject:message-id; bh=g+H/ekm4a1tNd9/uuqmtmBcE1liUdfh8+ZrY8uuygvc=; b=owEBbQKS/ZANAwAIAUPekfkkmnFFAcsmYgBnxdKBHjjvy8tJ6tgEh+AwC3Jkd3H0+XFY0/gXW t4ScrjR/0CJAjMEAAEIAB0WIQRN4NgY5dV16NRar8VD3pH5JJpxRQUCZ8XSgQAKCRBD3pH5JJpx RTkED/9yHuHpKSVb3fqOOKfB4WRC+qMYWAWVCK3TOiNvZocH5pByQ5r89T4HuwxvujIchsbIIaQ z/+DNTg9IdlVOxivcqjcOWjlhFf0G03yfDdbH73GtRQAA8NGYLV0SNyp92HxmxeUyhXvTozx5HI eOzUr47O4iNG8cGsfiglLbHdwptQ42qYQ/UDV0Cf3Df6V7hqxMoUFfdPZDY2RufjcaMB4R+bda5 Knz2eFe5cxZY/3ogfsAUBNb7kKW10ZNotN4J9pthPHYkw/l/LDoIDP7HVCFJCYEfKLvLmJ5oTsP pSTky242R/AdL2Fuw3ieSl3XpcSygUHPd0cIKOFuOLYSH9Cp+XTAe944ZtJdMCbN5bSvccxMwU1 7b16xcZ6slwTMfSaWE6rzN/pjcS8GgpfsYhCgfOKpZi0/zCLkqzue2Twoq0IUGaipZBXHxteBNO +3hPs/7yclikcTg4BcFYsP9ap+Uouzy/R4vXSsTSC4fCHh5SVI0JScvxR8/G45kkqb4OlmoxgWh tT2tuBtMFFVBGSvch+GGZ2T4Xnvg/RTywYgu/gQKTlwLdss5NeRFkU7pzXpqq9o32sPsCVG3bWq QIWml8SEzrFgjbfxUsBqRRUuJuM0EPpS7bdNWJtVYnvcTvW7sy+UAWIK3Mbg2gTVut7GdQ6OkjA v2g5C3RfHHsqAfw== X-Developer-Key: i=jai.luthra@ideasonboard.com; a=openpgp; fpr=4DE0D818E5D575E8D45AAFC543DE91F9249A7145 For continuous PLL lock, it is recommended to extend the temperature ramp down range of the DS90UB953-Q1 serializer based on the device's initial temperature [1]. The serializer's die temperature is reported only to the deserializer through the sensor status registers, and for UB9702, it is recommended to set the temperature ramp during the link setup sequence, i.e. before we even probe the ub953 driver. Add support to the deserializer driver to configure ub953's temperature ramp. [1]: Section 7.3.1.1 - https://www.ti.com/lit/gpn/ds90ub953-q1 Signed-off-by: Jai Luthra --- drivers/media/i2c/ds90ub953.h | 7 ++- drivers/media/i2c/ds90ub960.c | 125 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 131 insertions(+), 1 deletion(-) diff --git a/drivers/media/i2c/ds90ub953.h b/drivers/media/i2c/ds90ub953.h index de606474493f8d95a412e5564b0fac21885e581d..97a6b3af326eb96af20653ed13b89798e18646bd 100644 --- a/drivers/media/i2c/ds90ub953.h +++ b/drivers/media/i2c/ds90ub953.h @@ -71,7 +71,7 @@ /* Indirect register blocks */ #define UB953_IND_TARGET_PAT_GEN 0x00 -#define UB953_IND_TARGET_FPD3_TX 0x01 +#define UB953_IND_TARGET_ANALOG 0x01 #define UB953_IND_TARGET_DIE_ID 0x02 #define UB953_IND_PGEN_CTL 0x01 @@ -92,6 +92,11 @@ #define UB953_IND_PGEN_VFP 0x0f #define UB953_IND_PGEN_COLOR(n) (0x10 + (n)) /* n <= 15 */ +#define UB953_IND_ANA_TEMP_DYNAMIC_CFG 0x4b +#define UB953_IND_ANA_TEMP_DYNAMIC_CFG_OV BIT(5) +#define UB953_IND_ANA_TEMP_STATIC_CFG 0x4c +#define UB953_IND_ANA_TEMP_STATIC_CFG_MASK GENMASK(6, 4) + /* UB971 Registers */ #define UB971_ENH_BC_CHK 0x4b diff --git a/drivers/media/i2c/ds90ub960.c b/drivers/media/i2c/ds90ub960.c index cad25dcbca11bf6597d00eede6dfa9110f445886..1877eb735cc7d865a68e315446a24b536b387d2a 100644 --- a/drivers/media/i2c/ds90ub960.c +++ b/drivers/media/i2c/ds90ub960.c @@ -2017,6 +2017,110 @@ static int ub960_rxport_serializer_write(struct ub960_rxport *rxport, u8 reg, return ret; } +static int ub960_rxport_serializer_read(struct ub960_rxport *rxport, u8 reg, + u8 *val, int *err) +{ + struct ub960_data *priv = rxport->priv; + struct device *dev = &priv->client->dev; + union i2c_smbus_data data = { 0 }; + int ret; + + if (err && *err) + return *err; + + ret = i2c_smbus_xfer(priv->client->adapter, rxport->ser.alias, + priv->client->flags, I2C_SMBUS_READ, reg, + I2C_SMBUS_BYTE_DATA, &data); + if (ret) + dev_err(dev, + "rx%u: cannot read serializer register 0x%02x (%d)!\n", + rxport->nport, reg, ret); + else + *val = data.byte; + + if (ret && err) + *err = ret; + + return ret; +} + +static int ub960_serializer_temp_ramp(struct ub960_rxport *rxport) +{ + struct ub960_data *priv = rxport->priv; + short temp_dynamic_offset[] = {-1, -1, 0, 0, 1, 1, 1, 3}; + u8 temp_dynamic_cfg; + u8 nport = rxport->nport; + u8 ser_temp_code; + int ret; + + /* Configure temp ramp only on UB953 */ + if (!fwnode_device_is_compatible(rxport->ser.fwnode, "ti,ds90ub953-q1")) + return 0; + + /* Read current serializer die temperature */ + ub960_rxport_read(priv, nport, UB960_RR_SENSOR_STS_2, &ser_temp_code, + &ret); + + /* Enable I2C passthrough on back channel */ + ub960_rxport_update_bits(priv, nport, UB960_RR_BCC_CONFIG, + UB960_RR_BCC_CONFIG_I2C_PASS_THROUGH, + UB960_RR_BCC_CONFIG_I2C_PASS_THROUGH, &ret); + + if (ret) + return ret; + + /* Select indirect page for analog regs on the serializer */ + ub960_rxport_serializer_write(rxport, UB953_REG_IND_ACC_CTL, + UB953_IND_TARGET_ANALOG << 2, &ret); + + /* Set temperature ramp dynamic and static config */ + ub960_rxport_serializer_write(rxport, UB953_REG_IND_ACC_ADDR, + UB953_IND_ANA_TEMP_DYNAMIC_CFG, &ret); + ub960_rxport_serializer_read(rxport, UB953_REG_IND_ACC_DATA, + &temp_dynamic_cfg, &ret); + + if (ret) + return ret; + + temp_dynamic_cfg |= UB953_IND_ANA_TEMP_DYNAMIC_CFG_OV; + temp_dynamic_cfg += temp_dynamic_offset[ser_temp_code]; + + /* Update temp static config */ + ub960_rxport_serializer_write(rxport, UB953_REG_IND_ACC_ADDR, + UB953_IND_ANA_TEMP_STATIC_CFG, &ret); + ub960_rxport_serializer_write(rxport, UB953_REG_IND_ACC_DATA, + UB953_IND_ANA_TEMP_STATIC_CFG_MASK, &ret); + + /* Update temperature ramp dynamic config */ + ub960_rxport_serializer_write(rxport, UB953_REG_IND_ACC_ADDR, + UB953_IND_ANA_TEMP_DYNAMIC_CFG, &ret); + + /* Enable I2C auto ack on BC before we set dynamic cfg and reset */ + ub960_rxport_update_bits(priv, nport, UB960_RR_BCC_CONFIG, + UB960_RR_BCC_CONFIG_AUTO_ACK_ALL, + UB960_RR_BCC_CONFIG_AUTO_ACK_ALL, &ret); + + ub960_rxport_serializer_write(rxport, UB953_REG_IND_ACC_DATA, + temp_dynamic_cfg, &ret); + + if (ret) + return ret; + + /* Soft reset to apply PLL updates */ + ub960_rxport_serializer_write(rxport, UB953_REG_RESET_CTL, + UB953_REG_RESET_CTL_DIGITAL_RESET_0, + &ret); + msleep(20); + + /* Disable I2C passthrough and auto-ack on BC */ + ub960_rxport_update_bits(priv, nport, UB960_RR_BCC_CONFIG, + UB960_RR_BCC_CONFIG_I2C_PASS_THROUGH | + UB960_RR_BCC_CONFIG_AUTO_ACK_ALL, + 0x0, &ret); + + return ret; +} + static int ub960_rxport_bc_ser_config(struct ub960_rxport *rxport) { struct ub960_data *priv = rxport->priv; @@ -2396,6 +2500,20 @@ static int ub960_init_rx_ports_ub960(struct ub960_data *priv) return ret; } + /* Set temperature ramp on serializer */ + for_each_active_rxport(priv, it) { + ret = ub960_serializer_temp_ramp(it.rxport); + if (ret) + return ret; + + ub960_rxport_update_bits(priv, it.nport, UB960_RR_BCC_CONFIG, + UB960_RR_BCC_CONFIG_I2C_PASS_THROUGH, + UB960_RR_BCC_CONFIG_I2C_PASS_THROUGH, + &ret); + if (ret) + return ret; + } + /* * Clear any errors caused by switching the RX port settings while * probing. @@ -3071,6 +3189,13 @@ static int ub960_init_rx_ports_ub9702(struct ub960_data *priv) /* Wait time for stable lock */ fsleep(15000); + /* Set temperature ramp on serializer */ + for_each_active_rxport(priv, it) { + ret = ub960_serializer_temp_ramp(it.rxport); + if (ret) + return ret; + } + for_each_active_rxport_fpd4(priv, it) { ret = ub960_enable_dfe_lms_ub9702(priv, it.nport); if (ret)