From patchwork Fri Jan 10 09:14:01 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tomi Valkeinen X-Patchwork-Id: 13934023 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 C8F32209F31; Fri, 10 Jan 2025 09:15:10 +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=1736500512; cv=none; b=IYXwjpXfPaIR2068E/vJBGCh/zuWQnPlT/BotP0S1TXlQ66TYHSDqvC9QO520Q1/YWCpjnymhLlSR6GyoAKL3kXmVjfj2rnOwv1rHb/R1OKPo4RjCqZQk2FphLuSapEx6VgFZRzDC/RemhqXRCDcc2+SbPaogn8KBbIFQocfc34= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1736500512; c=relaxed/simple; bh=jvxUWvN2M6OAGbmHyJyxwhZ9FVde0WTx8Uk38EihmOg=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=GB3nIdRNk19Z0+A9EPkWl3mYJBYPNoA2a5UdU7llm3adY5ZpEXFqqIXdxp66VUS485dNO8UUNTxIlh5EvRZ0aClZbUmf2rfA/e8or4FjJfHhHcF7gDD2qWKBC4XONRWkDgQDThyUnTxHxy5bZtLhpVoNPfb6FnZAeqK4X5LFN38= 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=TT2D/FJL; 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="TT2D/FJL" Received: from [127.0.1.1] (91-158-153-178.elisa-laajakaista.fi [91.158.153.178]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id DC4EC8FA; Fri, 10 Jan 2025 10:14:10 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1736500451; bh=jvxUWvN2M6OAGbmHyJyxwhZ9FVde0WTx8Uk38EihmOg=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=TT2D/FJLSbchbZcSaUcDSV7qNs5aLcFltFomFzwXakFzext0reoJurVFu6XznUgOo IWjDIrFdb7V6b+hfGifRnOaLPDUyM5DbkYKA0GT9xXYl7KMisnZ/8iz+4P4AcOD0Sx Q0hQHJEB+ye4CCLamArPi8olXCtitnS8jWKL/MUo= From: Tomi Valkeinen Date: Fri, 10 Jan 2025 11:14:01 +0200 Subject: [PATCH 01/19] media: i2c: ds90ub953: Fix error prints Precedence: bulk X-Mailing-List: linux-media@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20250110-ub9xx-improvements-v1-1-e0b9a1f644da@ideasonboard.com> References: <20250110-ub9xx-improvements-v1-0-e0b9a1f644da@ideasonboard.com> In-Reply-To: <20250110-ub9xx-improvements-v1-0-e0b9a1f644da@ideasonboard.com> To: Mauro Carvalho Chehab Cc: linux-media@vger.kernel.org, linux-kernel@vger.kernel.org, Devarsh Thakkar , Jai Luthra , Sakari Ailus , Tomi Valkeinen X-Mailer: b4 0.13.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=2053; i=tomi.valkeinen@ideasonboard.com; h=from:subject:message-id; bh=jvxUWvN2M6OAGbmHyJyxwhZ9FVde0WTx8Uk38EihmOg=; b=owEBbQKS/ZANAwAIAfo9qoy8lh71AcsmYgBngOUQQ5A0Wb+F4qbnc9nbX34HHAxZI/Gpb/Ugk eAhLMUYUreJAjMEAAEIAB0WIQTEOAw+ll79gQef86f6PaqMvJYe9QUCZ4DlEAAKCRD6PaqMvJYe 9TwXD/9wvXHMAYxWpK4CxAIdgnpjTT+Loi8zuE6jfUeBLnbLCVMF9E2YIR0BDZRiWaiODvmcn91 OVrqDeWXg11F3IK2w9CSuFwclq3aFo7fsBmBK8yYBJnXP27ZPiSFEQe8Gvdx9ntqnpfAzihMlUs /NnxNl01OsjrY9CZfTCnZT9LO4Aflxe4xtp1qx40G+cmNu/9U7UNLFeJZt4uN6L09omqrnv5w1w 3p7FHXJXMz2wMF9QAjTJ90qJMIXRnsMGYkqixBDPYOpIdG5IHOU7RDIS0w7DbYHkNDsewFk4h18 CLbl7ILWWc+dKcg2lusbG68ys40K2HUrMBOOpr8jejVoKnuQrG3cLRcsQ+aGgZIZRXNNdsC9DnR z/MGAo6vsLGrhjVBbsJRS5dqOfquRakxZFFH509Ld1oeUbA6/x0bU1a0L2kure3Q6afV11Wai5C nykV4dm/ta0mHeJ1GaO3lK1cGspwNNxg6wPOCKMrZ/dneVsk7WnCwfpiLE6Hk9YURJejlejMi9q 4++xPvPf4+jAKFddzhiyCszmg0JMU1uTJrtj/4vSuMzV/5kQG2aplTtD++8q1JkxFRSOej9zR+z pcK8GggFxNDen6giwAnn7PkdjSBXjC6eLCQBzTlvBSC+JPXsnAy9m+FZVDW3VvDkbgJz8gd50z7 pVYVGR7BZQYbKaw== X-Developer-Key: i=tomi.valkeinen@ideasonboard.com; a=openpgp; fpr=C4380C3E965EFD81079FF3A7FA3DAA8CBC961EF5 ub953_read_ind() and ub953_write_ind() have broken error prints, and the register address is printed incorrectly. Fix the prints. Signed-off-by: Tomi Valkeinen --- drivers/media/i2c/ds90ub953.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/media/i2c/ds90ub953.c b/drivers/media/i2c/ds90ub953.c index 028892cfa361..fd1c442e8a07 100644 --- a/drivers/media/i2c/ds90ub953.c +++ b/drivers/media/i2c/ds90ub953.c @@ -258,7 +258,7 @@ static int ub953_read_ind(struct ub953_data *priv, u8 block, u8 reg, u8 *val) ret = regmap_write(priv->regmap, UB953_REG_IND_ACC_ADDR, reg); if (ret) { dev_err(&priv->client->dev, - "Write to IND_ACC_ADDR failed when reading %u:%x02x: %d\n", + "Write to IND_ACC_ADDR failed when reading %u:0x%02x: %d\n", block, reg, ret); goto out_unlock; } @@ -266,7 +266,7 @@ static int ub953_read_ind(struct ub953_data *priv, u8 block, u8 reg, u8 *val) ret = regmap_read(priv->regmap, UB953_REG_IND_ACC_DATA, &v); if (ret) { dev_err(&priv->client->dev, - "Write to IND_ACC_DATA failed when reading %u:%x02x: %d\n", + "Write to IND_ACC_DATA failed when reading %u:0x%02x: %d\n", block, reg, ret); goto out_unlock; } @@ -293,7 +293,7 @@ static int ub953_write_ind(struct ub953_data *priv, u8 block, u8 reg, u8 val) ret = regmap_write(priv->regmap, UB953_REG_IND_ACC_ADDR, reg); if (ret) { dev_err(&priv->client->dev, - "Write to IND_ACC_ADDR failed when writing %u:%x02x: %d\n", + "Write to IND_ACC_ADDR failed when writing %u:0x%02x: %d\n", block, reg, ret); goto out_unlock; } @@ -301,7 +301,7 @@ static int ub953_write_ind(struct ub953_data *priv, u8 block, u8 reg, u8 val) ret = regmap_write(priv->regmap, UB953_REG_IND_ACC_DATA, val); if (ret) { dev_err(&priv->client->dev, - "Write to IND_ACC_DATA failed when writing %u:%x02x\n: %d\n", + "Write to IND_ACC_DATA failed when writing %u:0x%02x: %d\n", block, reg, ret); } From patchwork Fri Jan 10 09:14:02 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tomi Valkeinen X-Patchwork-Id: 13934024 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 9EB4820A5DB; Fri, 10 Jan 2025 09:15:13 +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=1736500515; cv=none; b=K/SZlL8LFu81yEpPtLyqo8Yl/Xv8TAjHFPrnY+kqyNkD3AVnt1rchV956eOb8tTu95vWhPj76Im2NTgwY5Dl60WolkYbJjG4ArhPXLczafhf9UQT/RhfLmxTSf7B5HDeyi4H26nzoNFQo0Ys36vo0lmFHUAxUn8QgO2UB6TmMQQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1736500515; c=relaxed/simple; bh=+DE5YTRUaU0uLXaCLCAHD4D+g+T1LPnw/BYv7lanzh4=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=qIedzVXoUKqZLcpKnIs1S8h72xFm/HukwN3k+I1urp5wv3F6H1fa11E4E3MDcnJx2WGw3CBK1Zfcpkz/ylirL6/Fwo3dlaR23PxPTi8G9sY8bzY8V3/XFxgKBHbwVlh7LrfoQPmQuYZJ4IItZUpTtU4Oec0a87IkVjPETAnRwtk= 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=UJktk0Dh; 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="UJktk0Dh" Received: from [127.0.1.1] (91-158-153-178.elisa-laajakaista.fi [91.158.153.178]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 6FD9F11E9; Fri, 10 Jan 2025 10:14:11 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1736500451; bh=+DE5YTRUaU0uLXaCLCAHD4D+g+T1LPnw/BYv7lanzh4=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=UJktk0Dhty+WdlxqyLnPH7/LUeFeoL86qr8kF2d6HTioXe9NDcT4WQ5WPJU4Dm/tG 70Xr1FKgXt6iLvoBUQS44ccV71zIxvT2SZjADW8ebbnesQDqKdXeOnHre0N937ix7d Jxk2LLgku6dNpzb+JgqZ0Fbv4s5aecRwNHEVPuCA= From: Tomi Valkeinen Date: Fri, 10 Jan 2025 11:14:02 +0200 Subject: [PATCH 02/19] media: i2c: ds90ub913: Align ub913_read() with other similar functions Precedence: bulk X-Mailing-List: linux-media@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20250110-ub9xx-improvements-v1-2-e0b9a1f644da@ideasonboard.com> References: <20250110-ub9xx-improvements-v1-0-e0b9a1f644da@ideasonboard.com> In-Reply-To: <20250110-ub9xx-improvements-v1-0-e0b9a1f644da@ideasonboard.com> To: Mauro Carvalho Chehab Cc: linux-media@vger.kernel.org, linux-kernel@vger.kernel.org, Devarsh Thakkar , Jai Luthra , Sakari Ailus , Tomi Valkeinen X-Mailer: b4 0.13.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=999; i=tomi.valkeinen@ideasonboard.com; h=from:subject:message-id; bh=+DE5YTRUaU0uLXaCLCAHD4D+g+T1LPnw/BYv7lanzh4=; b=owEBbQKS/ZANAwAIAfo9qoy8lh71AcsmYgBngOURh6idaw0SbKrF8aJF3TYpqWEWXUEeXYpBV GJ4G9aVgmSJAjMEAAEIAB0WIQTEOAw+ll79gQef86f6PaqMvJYe9QUCZ4DlEQAKCRD6PaqMvJYe 9RZ7D/9ZLledoqvcvUgsxfufyzof1rAYR4Mq/TqA8H+vGy0FOooVWzvBzLmdnd29h4OeZM/tySt Lr9wXaTufjJBe7lMkagMf/3ki7C+D7JvGVx4Z9OYXqpDqqRrZI4JYjqKTwzm5TfST2kAckW6Lqe F/gYbkJt8uc7ZHPg6XLA04q1qnsaBdiMjRFx4PEhtOtm5+EwTcENbxYUA+jk9DNkZQnUEBh1mli iGtfM9EftiWhqcjuj47tF6vNY05BIsmycoJK7hB7PYRuhtM5aCKnuy/UjNI6pyrZAJHGFTZak2a eAQv7TDaVRrScInHQNTNwZa2ij5VKMExKLkiScIRwSz+2C4NM0u8w+aOMWzHLyvsZQ9AN+7i65l btcUo3Hr5OYWdM6zMIBMWXST09xTAaZIue0Vq8DX4wWSUgc3c56MHUxWZROp+q8k8UZ0PR2SNPJ i27K5hm89kse+b6fXRWrrQ4eKuu4ocetv88pz59kiJK/Roa4Ds8SFCL2+AJVcO7yJPCgMZ0PT62 kXsIrcLIX/yQurIDY0cUiJCo3TeIrSWMAk4gsAryVcT4Ue5giHofXYoWZhfQC5LrNLi/gjNZh/w JW+IgLpD9AQ9oSazThZdxRMRX4kG+0dDoXwDZ38xiJuwO2ltizotBeptljkUqh316iafMwCTMPd T4ZgH8nKIafwBzw== X-Developer-Key: i=tomi.valkeinen@ideasonboard.com; a=openpgp; fpr=C4380C3E965EFD81079FF3A7FA3DAA8CBC961EF5 Adjust the ub913_read() to have similar form than the other similar functions in ub9xx drivers. This makes it easier to deal with all the read/write functions with a semantic patch. Signed-off-by: Tomi Valkeinen --- drivers/media/i2c/ds90ub913.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/media/i2c/ds90ub913.c b/drivers/media/i2c/ds90ub913.c index 7670d6c82d92..1daf0b8ba726 100644 --- a/drivers/media/i2c/ds90ub913.c +++ b/drivers/media/i2c/ds90ub913.c @@ -125,14 +125,16 @@ static int ub913_read(const struct ub913_data *priv, u8 reg, u8 *val) int ret; ret = regmap_read(priv->regmap, reg, &v); - if (ret < 0) { + if (ret) { dev_err(&priv->client->dev, "Cannot read register 0x%02x: %d!\n", reg, ret); - return ret; + goto out; } *val = v; - return 0; + +out: + return ret; } static int ub913_write(const struct ub913_data *priv, u8 reg, u8 val) From patchwork Fri Jan 10 09:14:03 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tomi Valkeinen X-Patchwork-Id: 13934025 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 79C2420A5C2; Fri, 10 Jan 2025 09:15:14 +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=1736500520; cv=none; b=Ri6JrD9p5pn+cS05odC48ax6oioOLdDiz17KlVFGQooa2E/8b8POy/ZO4XAYHyjVCOKLOMvxESYTH5F4OyAmqD9hCRVUYj3xhcSuWg/0TAcT/yLrjaBXgekyP1cB4rxlu3MiWsau+BnKusQOcadiGFDcKKqhVCL0L2syjDtzi30= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1736500520; c=relaxed/simple; bh=GfG/2UBTzuwZDjl5YR7YN95lwpVU3k+JSMCrlY7At7U=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=lH6MkxI8n3bFfAmvPxLr3FS7UBuswKM+yfVZ5WWn9PXGXZrA1z96dYojSyKHs7jIeHF57x7/wDs236iTiQ/NOdApPtRGFGoHE4Kq8WDk5J2lhN3EEWln+g8oeUOnX+qlromxsqi7bsdb/UdqUuG01HVWv95IkqkeB0dHhJqezXY= 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=GTk9i/rL; 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="GTk9i/rL" Received: from [127.0.1.1] (91-158-153-178.elisa-laajakaista.fi [91.158.153.178]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 01FE41237; Fri, 10 Jan 2025 10:14:11 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1736500452; bh=GfG/2UBTzuwZDjl5YR7YN95lwpVU3k+JSMCrlY7At7U=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=GTk9i/rLwUFgyy6phnSiQZT/YGReJeVvfs3UmyHoMHXpU47IIrDKzIayEHfgbUNwP +kr2Gu+NrvQbD5KYq+5T9kuf1vFiA/NW4UVT4JlwuzCYTihnJE/3NggxTjn/BQ5V8N qLZhXH6O8hBD81pc3g6HLf6WZA5fe7kmTEbkHOkQ= From: Tomi Valkeinen Date: Fri, 10 Jan 2025 11:14:03 +0200 Subject: [PATCH 03/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: <20250110-ub9xx-improvements-v1-3-e0b9a1f644da@ideasonboard.com> References: <20250110-ub9xx-improvements-v1-0-e0b9a1f644da@ideasonboard.com> In-Reply-To: <20250110-ub9xx-improvements-v1-0-e0b9a1f644da@ideasonboard.com> To: Mauro Carvalho Chehab Cc: linux-media@vger.kernel.org, linux-kernel@vger.kernel.org, Devarsh Thakkar , Jai Luthra , Sakari Ailus , Tomi Valkeinen X-Mailer: b4 0.13.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=55589; i=tomi.valkeinen@ideasonboard.com; h=from:subject:message-id; bh=GfG/2UBTzuwZDjl5YR7YN95lwpVU3k+JSMCrlY7At7U=; b=owEBbQKS/ZANAwAIAfo9qoy8lh71AcsmYgBngOUR043wfsViZ9Agi6ChrHNoCxKuTJRvjg76V pUWF7C8OM6JAjMEAAEIAB0WIQTEOAw+ll79gQef86f6PaqMvJYe9QUCZ4DlEQAKCRD6PaqMvJYe 9ffAD/9mF0D6Ihw7JUCzfMt2x+EhfKAuGdgXFN545KoNzhUTey8gMKxv3kYrYyhMSyLyUlp6E5g +g8fmINaybYK/VQBt48hYRywGckLd6wFvgle4ZEZqk527vFNN02l64LE9+yKhF9kghHWhDi84H2 KYGaWp8VY2LVfpSf74ih4lgEhzcC1Q2+RCoqMpbFq1KNsatS5dmXtB/nyWlsragW7Jf2WJAKkG8 f5M+7tiZEK7QLTjSCZRQpKBGCKOt96pqvl4Z9Fv1trps+btraezMiAa721AhnaMsbVU0iY17cys OR3uJ0c9/lFF/DQ1vasv4H6Et4fEdGBp8paJMYTs3lL43jwyw0XP9gPy/Mu62ZLb+TSFSIotvSh rcAYCBHEX90eClVbzv6USRBVcTYrFcdm5X00IFe6OkM9WjR56s+87E+Uffr7gVxa7IyZuHjsmm1 C3UAumFAskwhrq7Z3XHVQUCVraGWUbl+PoaI9Bdk006yzqFk3QU5Tm8KdpugFVFiv1PSq4YSXY0 TQPYgvPdzn+zlhmSMxldevfa1fTlpQ0VSWNoghNyrqvi5toaBIY1pCcKi3EP9RHDNxKhfoQY93H lOOHh3D9/+QL6HFfj3qS6UdMRd8HMOGkmoo8Ot2SndX/fBkeRVJMRWX9KcGQqdWf2wUHOHEFt26 WyhfSMcC/jbqHKw== X-Developer-Key: i=tomi.valkeinen@ideasonboard.com; a=openpgp; fpr=C4380C3E965EFD81079FF3A7FA3DAA8CBC961EF5 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 --- 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 1daf0b8ba726..34f92aa1c56c 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 fd1c442e8a07..07d451816855 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 d1cc37246452..03986a2aaf2c 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 Fri Jan 10 09:14:04 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tomi Valkeinen X-Patchwork-Id: 13934026 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 655B220ADC4; Fri, 10 Jan 2025 09:15: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=1736500520; cv=none; b=SfJuRIsfgPO4MFLcn6R5tE9gXbacVGWs1Uj4frjFN5BbQXSZs+Y0hLaQyvbf60RmHHHqYUEwtIZf55ZHXVV2RBR49VnRsYTSmoj709DsD+cULsp2ajaeGRKcNQHiNpAn9zAcdphJicpNrSw+YpFBQb56equ1TTPiA+PunLp0OkM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1736500520; c=relaxed/simple; bh=dX7dExG+G47YrB7qoXEUKEdbVYixKTculMCgA5CAWs8=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=fU84a0H7D/GzLth2yPG72wT2I/C5+vqmVEGPyEr2s+T3nqR5qhEf+NSemKOxGspPbQOq03Dm/Zs+GEe8wiHBvt+2r9kXTcpryXGdbGJxmSMrhHJewNJeqH3J9whBqxyEcCro6z+fadsyyTUy+C4GPYUFvPCDB+0o6kvyiaMySh4= 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=eDBgSTQI; 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="eDBgSTQI" Received: from [127.0.1.1] (91-158-153-178.elisa-laajakaista.fi [91.158.153.178]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id A78BA1449; Fri, 10 Jan 2025 10:14:12 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1736500453; bh=dX7dExG+G47YrB7qoXEUKEdbVYixKTculMCgA5CAWs8=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=eDBgSTQIsr5wkAqlTLZQHA3uzFr0qe3oa1mgOC/C151cm64OoCwheHDnW9jhyk0lF 4z75eNvkdLXwiiR7juzya/LDPrY8PtSneLUQQCQ/pFe0+vSLKMn1b1OewsepXtClPt /VXuKZYfaLuMEnPtifWSxsA6pc7fMEz3ZL+bTZ/g= From: Tomi Valkeinen Date: Fri, 10 Jan 2025 11:14:04 +0200 Subject: [PATCH 04/19] media: i2c: ds90ub960: Add error handling to multiple places Precedence: bulk X-Mailing-List: linux-media@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20250110-ub9xx-improvements-v1-4-e0b9a1f644da@ideasonboard.com> References: <20250110-ub9xx-improvements-v1-0-e0b9a1f644da@ideasonboard.com> In-Reply-To: <20250110-ub9xx-improvements-v1-0-e0b9a1f644da@ideasonboard.com> To: Mauro Carvalho Chehab Cc: linux-media@vger.kernel.org, linux-kernel@vger.kernel.org, Devarsh Thakkar , Jai Luthra , Sakari Ailus , Tomi Valkeinen X-Mailer: b4 0.13.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=41182; i=tomi.valkeinen@ideasonboard.com; h=from:subject:message-id; bh=dX7dExG+G47YrB7qoXEUKEdbVYixKTculMCgA5CAWs8=; b=owEBbQKS/ZANAwAIAfo9qoy8lh71AcsmYgBngOURwP6A+SyDvirGx43Rt19aS+og4LS6MrL4w 28M4Ix+7NCJAjMEAAEIAB0WIQTEOAw+ll79gQef86f6PaqMvJYe9QUCZ4DlEQAKCRD6PaqMvJYe 9Q8cEACmI2/SJl6wTVsG33yhzUkgnUkO2J9TwSubjkfD9ec3fIkEG3NzdejBnAta0UW3hjsPa9p APgYzaTpv+tC+cYfT2KrtAcQ0mtFccJpc6frX4vG2oRmPsgrJuJlziqGYBl2UppS4vTAwYtDa9h ceeev3Nfro0909jhJZCJHsQA/sO82Sl20Rzub383ywUAWS91ncdd0cNadWruuBETPbfdZzrArhE hiTXjiztwkrTtd4oOlO89qUnMCnja/o6V0tmftEcirLA41xBF3JzBElYcCtv9SVT670Zlwy4R6y cThsQU28Gy24TJalJAHZwC6jk6yT9phDLn5WkQDs84Z6AmkWl0OdZ1PUGORwLjtKm3V4bRSBYaG yR6FrgD/xO30ArXx1XjTwqKj5LiBIX98kyJ9daPxmwX9U/FF/OJvSh+6VGUOBdYr0G04/JkLSu1 nBfk+x7liJHAGPo/8MWafi4dHWDJhWBCdabSmBfGwUwdrOoXVcLIT/1gRbv4qLlrCfIElcYnnQj UwRcyNo1s1LP/ckE1m/ULktEJsCX129muBCJb7/xD878PjwSzYQNqppwoFhoqJVa+Zg2WcwE0eJ N3lle55pDvTplc1yyLiMZlWlioaSgbH0KgCyL16WtjUGf9un/hG0f6KE3NnMbfZaXRVLeiTGZ/8 sYZrK1CMDZEPedg== X-Developer-Key: i=tomi.valkeinen@ideasonboard.com; a=openpgp; fpr=C4380C3E965EFD81079FF3A7FA3DAA8CBC961EF5 The driver is missing checks for i2c read/write errors in many places. Now that we have added the err parameter to the read/write functions in the previous patch, add error handling to all the missing places. Signed-off-by: Tomi Valkeinen --- drivers/media/i2c/ds90ub960.c | 589 +++++++++++++++++++++++++++--------------- 1 file changed, 376 insertions(+), 213 deletions(-) diff --git a/drivers/media/i2c/ds90ub960.c b/drivers/media/i2c/ds90ub960.c index 03986a2aaf2c..80bbba0792c1 100644 --- a/drivers/media/i2c/ds90ub960.c +++ b/drivers/media/i2c/ds90ub960.c @@ -1144,6 +1144,7 @@ static int ub960_atr_attach_client(struct i2c_atr *atr, u32 chan_id, struct ub960_rxport *rxport = priv->rxports[chan_id]; struct device *dev = &priv->client->dev; unsigned int reg_idx; + int ret = 0; for (reg_idx = 0; reg_idx < ARRAY_SIZE(rxport->aliased_clients); reg_idx++) { if (!rxport->aliased_clients[reg_idx]) @@ -1158,9 +1159,12 @@ 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, NULL); + client->addr << 1, &ret); ub960_rxport_write(priv, chan_id, UB960_RR_SLAVE_ALIAS(reg_idx), - alias << 1, NULL); + alias << 1, &ret); + + if (ret) + return ret; dev_dbg(dev, "rx%u: client 0x%02x assigned alias 0x%02x at slot %u\n", rxport->nport, client->addr, alias, reg_idx); @@ -1175,6 +1179,7 @@ static void ub960_atr_detach_client(struct i2c_atr *atr, u32 chan_id, struct ub960_rxport *rxport = priv->rxports[chan_id]; struct device *dev = &priv->client->dev; unsigned int reg_idx; + int ret; for (reg_idx = 0; reg_idx < ARRAY_SIZE(rxport->aliased_clients); reg_idx++) { if (rxport->aliased_clients[reg_idx] == client) @@ -1189,8 +1194,13 @@ 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, - NULL); + ret = ub960_rxport_write(priv, chan_id, UB960_RR_SLAVE_ALIAS(reg_idx), + 0, NULL); + if (ret) { + dev_err(dev, "rx%u: unable to fully unmap client 0x%02x: %d\n", + rxport->nport, client->addr, ret); + return; + } dev_dbg(dev, "rx%u: client 0x%02x released at slot %u\n", rxport->nport, client->addr, reg_idx); @@ -1285,7 +1295,7 @@ static int ub960_parse_dt_txport(struct ub960_data *priv, return ret; } -static void ub960_csi_handle_events(struct ub960_data *priv, u8 nport) +static int ub960_csi_handle_events(struct ub960_data *priv, u8 nport) { struct device *dev = &priv->client->dev; u8 csi_tx_isr; @@ -1294,13 +1304,15 @@ static void ub960_csi_handle_events(struct ub960_data *priv, u8 nport) ret = ub960_txport_read(priv, nport, UB960_TR_CSI_TX_ISR, &csi_tx_isr, NULL); if (ret) - return; + return ret; if (csi_tx_isr & UB960_TR_CSI_TX_ISR_IS_CSI_SYNC_ERROR) dev_warn(dev, "TX%u: CSI_SYNC_ERROR\n", nport); if (csi_tx_isr & UB960_TR_CSI_TX_ISR_IS_CSI_PASS_ERROR) dev_warn(dev, "TX%u: CSI_PASS_ERROR\n", nport); + + return 0; } /* ----------------------------------------------------------------------------- @@ -1352,28 +1364,38 @@ static void ub960_rxport_disable_vpocs(struct ub960_data *priv) } } -static void ub960_rxport_clear_errors(struct ub960_data *priv, - unsigned int nport) +static int ub960_rxport_clear_errors(struct ub960_data *priv, + unsigned int nport) { + int ret = 0; u8 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_PORT_STS1, &v, &ret); + ub960_rxport_read(priv, nport, UB960_RR_RX_PORT_STS2, &v, &ret); + ub960_rxport_read(priv, nport, UB960_RR_CSI_RX_STS, &v, &ret); + ub960_rxport_read(priv, nport, UB960_RR_BCC_STATUS, &v, &ret); - 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_RX_PAR_ERR_HI, &v, &ret); + ub960_rxport_read(priv, nport, UB960_RR_RX_PAR_ERR_LO, &v, &ret); - ub960_rxport_read(priv, nport, UB960_RR_CSI_ERR_COUNTER, &v, NULL); + ub960_rxport_read(priv, nport, UB960_RR_CSI_ERR_COUNTER, &v, &ret); + + return ret; } -static void ub960_clear_rx_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++) - ub960_rxport_clear_errors(priv, nport); + for (nport = 0; nport < priv->hw_data->num_rxports; nport++) { + int ret; + + ret = ub960_rxport_clear_errors(priv, nport); + if (ret) + return ret; + } + + return 0; } static int ub960_rxport_get_strobe_pos(struct ub960_data *priv, @@ -1383,14 +1405,18 @@ static int ub960_rxport_get_strobe_pos(struct ub960_data *priv, u8 clk_delay, data_delay; int ret; - ub960_read_ind(priv, UB960_IND_TARGET_RX_ANA(nport), - UB960_IR_RX_ANA_STROBE_SET_CLK, &v, NULL); + ret = ub960_read_ind(priv, UB960_IND_TARGET_RX_ANA(nport), + UB960_IR_RX_ANA_STROBE_SET_CLK, &v, NULL); + if (ret) + return ret; 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, NULL); + ret = ub960_read_ind(priv, UB960_IND_TARGET_RX_ANA(nport), + UB960_IR_RX_ANA_STROBE_SET_DATA, &v, NULL); + if (ret) + return ret; data_delay = (v & UB960_IR_RX_ANA_STROBE_SET_DATA_NO_EXTRA_DELAY) ? 0 : UB960_MANUAL_STROBE_EXTRA_DELAY; @@ -1412,10 +1438,11 @@ static int ub960_rxport_get_strobe_pos(struct ub960_data *priv, return 0; } -static void ub960_rxport_set_strobe_pos(struct ub960_data *priv, - unsigned int nport, s8 strobe_pos) +static int ub960_rxport_set_strobe_pos(struct ub960_data *priv, + unsigned int nport, s8 strobe_pos) { u8 clk_delay, data_delay; + int ret = 0; clk_delay = UB960_IR_RX_ANA_STROBE_SET_CLK_NO_EXTRA_DELAY; data_delay = UB960_IR_RX_ANA_STROBE_SET_DATA_NO_EXTRA_DELAY; @@ -1430,23 +1457,25 @@ 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, NULL); + UB960_IR_RX_ANA_STROBE_SET_CLK, clk_delay, &ret); ub960_write_ind(priv, UB960_IND_TARGET_RX_ANA(nport), - UB960_IR_RX_ANA_STROBE_SET_DATA, data_delay, NULL); + UB960_IR_RX_ANA_STROBE_SET_DATA, data_delay, &ret); + + return ret; } -static void ub960_rxport_set_strobe_range(struct ub960_data *priv, - s8 strobe_min, s8 strobe_max) +static int ub960_rxport_set_strobe_range(struct ub960_data *priv, s8 strobe_min, + s8 strobe_max) { /* Convert the signed strobe pos to positive zero based value */ strobe_min -= UB960_MIN_AEQ_STROBE_POS; strobe_max -= UB960_MIN_AEQ_STROBE_POS; - 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), - NULL); + return 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), + NULL); } static int ub960_rxport_get_eq_level(struct ub960_data *priv, @@ -1465,11 +1494,12 @@ static int ub960_rxport_get_eq_level(struct ub960_data *priv, return 0; } -static void ub960_rxport_set_eq_level(struct ub960_data *priv, - unsigned int nport, u8 eq_level) +static int ub960_rxport_set_eq_level(struct ub960_data *priv, + unsigned int nport, u8 eq_level) { u8 eq_stage_1_select_value, eq_stage_2_select_value; const unsigned int eq_stage_max = 7; + int ret; u8 v; if (eq_level <= eq_stage_max) { @@ -1480,7 +1510,9 @@ 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, NULL); + ret = ub960_rxport_read(priv, nport, UB960_RR_AEQ_BYPASS, &v, NULL); + if (ret) + return ret; v &= ~(UB960_RR_AEQ_BYPASS_EQ_STAGE1_VALUE_MASK | UB960_RR_AEQ_BYPASS_EQ_STAGE2_VALUE_MASK); @@ -1488,68 +1520,102 @@ 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, NULL); + ret = ub960_rxport_write(priv, nport, UB960_RR_AEQ_BYPASS, v, NULL); + if (ret) + return ret; + + return 0; } -static void ub960_rxport_set_eq_range(struct ub960_data *priv, - unsigned int nport, u8 eq_min, u8 eq_max) +static int ub960_rxport_set_eq_range(struct ub960_data *priv, + unsigned int nport, u8 eq_min, u8 eq_max) { + int ret = 0; + 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), - NULL); + &ret); /* 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, NULL); + UB960_RR_AEQ_CTL2_SET_AEQ_FLOOR, &ret); + + return ret; } -static void ub960_rxport_config_eq(struct ub960_data *priv, unsigned int nport) +static int ub960_rxport_config_eq(struct ub960_data *priv, unsigned int nport) { struct ub960_rxport *rxport = priv->rxports[nport]; + int ret; /* We also set common settings here. Should be moved elsewhere. */ if (priv->strobe.manual) { /* Disable AEQ_SFILTER_EN */ - ub960_update_bits(priv, UB960_XR_AEQ_CTL1, - UB960_XR_AEQ_CTL1_AEQ_SFILTER_EN, 0, NULL); + ret = ub960_update_bits(priv, UB960_XR_AEQ_CTL1, + UB960_XR_AEQ_CTL1_AEQ_SFILTER_EN, 0, + NULL); + if (ret) + return ret; } 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, NULL); + ret = ub960_write(priv, UB960_XR_AEQ_CTL1, + UB960_XR_AEQ_CTL1_AEQ_ERR_CTL_MASK | + UB960_XR_AEQ_CTL1_AEQ_SFILTER_EN, + NULL); + + if (ret) + return ret; /* Set AEQ strobe range */ - ub960_rxport_set_strobe_range(priv, priv->strobe.min, - priv->strobe.max); + ret = ub960_rxport_set_strobe_range(priv, priv->strobe.min, + priv->strobe.max); + if (ret) + return ret; } /* The rest are port specific */ if (priv->strobe.manual) - ub960_rxport_set_strobe_pos(priv, nport, rxport->eq.strobe_pos); + ret = ub960_rxport_set_strobe_pos(priv, nport, + rxport->eq.strobe_pos); else - ub960_rxport_set_strobe_pos(priv, nport, 0); + ret = ub960_rxport_set_strobe_pos(priv, nport, 0); + + if (ret) + return ret; if (rxport->eq.manual_eq) { - ub960_rxport_set_eq_level(priv, nport, - rxport->eq.manual.eq_level); + ret = ub960_rxport_set_eq_level(priv, nport, + rxport->eq.manual.eq_level); + if (ret) + return ret; /* Enable AEQ Bypass */ - ub960_rxport_update_bits(priv, nport, UB960_RR_AEQ_BYPASS, - UB960_RR_AEQ_BYPASS_ENABLE, - UB960_RR_AEQ_BYPASS_ENABLE, NULL); + ret = ub960_rxport_update_bits(priv, nport, UB960_RR_AEQ_BYPASS, + UB960_RR_AEQ_BYPASS_ENABLE, + UB960_RR_AEQ_BYPASS_ENABLE, + NULL); + if (ret) + return ret; } else { - ub960_rxport_set_eq_range(priv, nport, - rxport->eq.aeq.eq_level_min, - rxport->eq.aeq.eq_level_max); + ret = ub960_rxport_set_eq_range(priv, nport, + rxport->eq.aeq.eq_level_min, + rxport->eq.aeq.eq_level_max); + if (ret) + return ret; /* Disable AEQ Bypass */ - ub960_rxport_update_bits(priv, nport, UB960_RR_AEQ_BYPASS, - UB960_RR_AEQ_BYPASS_ENABLE, 0, NULL); + ret = ub960_rxport_update_bits(priv, nport, UB960_RR_AEQ_BYPASS, + UB960_RR_AEQ_BYPASS_ENABLE, 0, + NULL); + if (ret) + return ret; } + + return 0; } static int ub960_rxport_link_ok(struct ub960_data *priv, unsigned int nport, @@ -1697,8 +1763,11 @@ static int ub960_rxport_wait_locks(struct ub960_data *priv, continue; } - ub960_rxport_read16(priv, nport, UB960_RR_RX_FREQ_HIGH, &v, - NULL); + ret = ub960_rxport_read16(priv, nport, UB960_RR_RX_FREQ_HIGH, + &v, NULL); + + if (ret) + return ret; if (priv->hw_data->is_ub9702) { dev_dbg(dev, "\trx%u: locked, freq %llu Hz\n", @@ -1867,8 +1936,8 @@ static void ub960_rxport_remove_serializers(struct ub960_data *priv) } } -static void ub960_init_tx_port(struct ub960_data *priv, - struct ub960_txport *txport) +static int ub960_init_tx_port(struct ub960_data *priv, + struct ub960_txport *txport) { unsigned int nport = txport->nport; u8 csi_ctl = 0; @@ -1885,7 +1954,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, NULL); + return ub960_txport_write(priv, nport, UB960_TR_CSI_CTL, csi_ctl, NULL); } static int ub960_init_tx_ports(struct ub960_data *priv) @@ -1893,6 +1962,7 @@ static int ub960_init_tx_ports(struct ub960_data *priv) unsigned int nport; u8 speed_select; u8 pll_div; + int ret = 0; /* TX ports */ @@ -1916,51 +1986,57 @@ static int ub960_init_tx_ports(struct ub960_data *priv) break; } - ub960_write(priv, UB960_SR_CSI_PLL_CTL, speed_select, NULL); + 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, NULL); + ub960_write(priv, UB960_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, NULL); + 0x80, &ret); ub960_write_ind(priv, UB960_IND_TARGET_CSI_ANA, 0x4b, - 0x2a, NULL); + 0x2a, &ret); break; case MHZ(800): ub960_write_ind(priv, UB960_IND_TARGET_CSI_ANA, 0x92, - 0x90, NULL); + 0x90, &ret); ub960_write_ind(priv, UB960_IND_TARGET_CSI_ANA, 0x4f, - 0x2a, NULL); + 0x2a, &ret); ub960_write_ind(priv, UB960_IND_TARGET_CSI_ANA, 0x4b, - 0x2a, NULL); + 0x2a, &ret); break; case MHZ(400): ub960_write_ind(priv, UB960_IND_TARGET_CSI_ANA, 0x92, - 0xa0, NULL); + 0xa0, &ret); break; } } + if (ret) + return ret; + for (nport = 0; nport < priv->hw_data->num_txports; nport++) { struct ub960_txport *txport = priv->txports[nport]; if (!txport) continue; - ub960_init_tx_port(priv, txport); + ret = ub960_init_tx_port(priv, txport); + if (ret) + return ret; } return 0; } -static void ub960_init_rx_port_ub960(struct ub960_data *priv, - struct ub960_rxport *rxport) +static int ub960_init_rx_port_ub960(struct ub960_data *priv, + struct ub960_rxport *rxport) { unsigned int nport = rxport->nport; u32 bc_freq_val; + int ret = 0; /* * Back channel frequency select. @@ -1989,19 +2065,19 @@ static void ub960_init_rx_port_ub960(struct ub960_data *priv, break; default: - return; + return -EINVAL; } ub960_rxport_update_bits(priv, nport, UB960_RR_BCC_CONFIG, UB960_RR_BCC_CONFIG_BC_FREQ_SEL_MASK, - bc_freq_val, NULL); + bc_freq_val, &ret); 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, NULL); + 0x3, &ret); /* * RAW10_8BIT_CTL = 0b10 : 8-bit processing using upper 8 bits @@ -2009,55 +2085,58 @@ static void ub960_init_rx_port_ub960(struct ub960_data *priv, 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, - NULL); + &ret); break; case RXPORT_MODE_RAW12_HF: case RXPORT_MODE_RAW12_LF: /* Not implemented */ - return; + return -EINVAL; case RXPORT_MODE_CSI2_SYNC: case RXPORT_MODE_CSI2_NONSYNC: /* CSI-2 Mode (DS90UB953-Q1 compatible) */ ub960_rxport_update_bits(priv, nport, UB960_RR_PORT_CONFIG, 0x3, - 0x0, NULL); + 0x0, &ret); break; } /* LV_POLARITY & FV_POLARITY */ ub960_rxport_update_bits(priv, nport, UB960_RR_PORT_CONFIG2, 0x3, - rxport->lv_fv_pol, NULL); + rxport->lv_fv_pol, &ret); /* Enable all interrupt sources from this port */ - ub960_rxport_write(priv, nport, UB960_RR_PORT_ICR_HI, 0x07, NULL); - ub960_rxport_write(priv, nport, UB960_RR_PORT_ICR_LO, 0x7f, NULL); + ub960_rxport_write(priv, nport, UB960_RR_PORT_ICR_HI, 0x07, &ret); + ub960_rxport_write(priv, nport, UB960_RR_PORT_ICR_LO, 0x7f, &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, NULL); + UB960_RR_BCC_CONFIG_I2C_PASS_THROUGH, &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, NULL); + rxport->ser.alias << 1, &ret); /* 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), - NULL); + &ret); + + return ret; } -static void ub960_init_rx_port_ub9702_fpd3(struct ub960_data *priv, - struct ub960_rxport *rxport) +static int ub960_init_rx_port_ub9702_fpd3(struct ub960_data *priv, + struct ub960_rxport *rxport) { unsigned int nport = rxport->nport; u8 bc_freq_val; u8 fpd_func_mode; + int ret = 0; switch (rxport->rx_mode) { case RXPORT_MODE_RAW10: @@ -2086,90 +2165,96 @@ static void ub960_init_rx_port_ub9702_fpd3(struct ub960_data *priv, break; default: - return; + return -EINVAL; } ub960_rxport_update_bits(priv, nport, UB960_RR_BCC_CONFIG, 0x7, - bc_freq_val, NULL); + bc_freq_val, &ret); ub960_rxport_write(priv, nport, UB960_RR_CHANNEL_MODE, fpd_func_mode, - NULL); + &ret); /* set serdes_eq_mode = 1 */ ub960_write_ind(priv, UB960_IND_TARGET_RX_ANA(nport), 0xa8, 0x80, - NULL); + &ret); /* enable serdes driver */ ub960_write_ind(priv, UB960_IND_TARGET_RX_ANA(nport), 0x0d, 0x7f, - NULL); + &ret); /* set serdes_eq_offset=4 */ ub960_write_ind(priv, UB960_IND_TARGET_RX_ANA(nport), 0x2b, 0x04, - NULL); + &ret); /* init default serdes_eq_max in 0xa9 */ ub960_write_ind(priv, UB960_IND_TARGET_RX_ANA(nport), 0xa9, 0x23, - NULL); + &ret); /* init serdes_eq_min in 0xaa */ - ub960_write_ind(priv, UB960_IND_TARGET_RX_ANA(nport), 0xaa, 0, NULL); + ub960_write_ind(priv, UB960_IND_TARGET_RX_ANA(nport), 0xaa, 0, &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), NULL); + BIT(3), BIT(3), &ret); /* RX port to half-rate */ ub960_update_bits(priv, UB960_SR_FPD_RATE_CFG, 0x3 << (nport * 2), - BIT(nport * 2), NULL); + BIT(nport * 2), &ret); + + return ret; } -static void ub960_init_rx_port_ub9702_fpd4_aeq(struct ub960_data *priv, - struct ub960_rxport *rxport) +static int ub960_init_rx_port_ub9702_fpd4_aeq(struct ub960_data *priv, + struct ub960_rxport *rxport) { unsigned int nport = rxport->nport; bool first_time_power_up = true; + int ret = 0; if (first_time_power_up) { u8 v; /* AEQ init */ ub960_read_ind(priv, UB960_IND_TARGET_RX_ANA(nport), 0x2c, &v, - NULL); + &ret); ub960_write_ind(priv, UB960_IND_TARGET_RX_ANA(nport), 0x27, v, - NULL); + &ret); ub960_write_ind(priv, UB960_IND_TARGET_RX_ANA(nport), 0x28, - v + 1, NULL); + v + 1, &ret); ub960_write_ind(priv, UB960_IND_TARGET_RX_ANA(nport), 0x2b, - 0x00, NULL); + 0x00, &ret); } /* enable serdes_eq_ctl2 */ ub960_write_ind(priv, UB960_IND_TARGET_RX_ANA(nport), 0x9e, 0x00, - NULL); + &ret); /* enable serdes_eq_ctl1 */ ub960_write_ind(priv, UB960_IND_TARGET_RX_ANA(nport), 0x90, 0x40, - NULL); + &ret); /* enable serdes_eq_en */ ub960_write_ind(priv, UB960_IND_TARGET_RX_ANA(nport), 0x2e, 0x40, - NULL); + &ret); /* disable serdes_eq_override */ ub960_write_ind(priv, UB960_IND_TARGET_RX_ANA(nport), 0xf0, 0x00, - NULL); + &ret); /* disable serdes_gain_override */ ub960_write_ind(priv, UB960_IND_TARGET_RX_ANA(nport), 0x71, 0x00, - NULL); + &ret); + + return ret; } -static void ub960_init_rx_port_ub9702_fpd4(struct ub960_data *priv, - struct ub960_rxport *rxport) +static int ub960_init_rx_port_ub9702_fpd4(struct ub960_data *priv, + struct ub960_rxport *rxport) { unsigned int nport = rxport->nport; u8 bc_freq_val; + int ret = 0; switch (rxport->rx_mode) { case RXPORT_MODE_RAW10: @@ -2193,55 +2278,66 @@ static void ub960_init_rx_port_ub9702_fpd4(struct ub960_data *priv, break; default: - return; + return -EINVAL; } ub960_rxport_update_bits(priv, nport, UB960_RR_BCC_CONFIG, 0x7, - bc_freq_val, NULL); + bc_freq_val, &ret); /* FPD4 Sync Mode */ - ub960_rxport_write(priv, nport, UB960_RR_CHANNEL_MODE, 0, NULL); + ub960_rxport_write(priv, nport, UB960_RR_CHANNEL_MODE, 0, &ret); /* add serdes_eq_offset of 4 */ ub960_write_ind(priv, UB960_IND_TARGET_RX_ANA(nport), 0x2b, 0x04, - NULL); + &ret); /* FPD4 serdes_start_eq in 0x27: assign default */ - ub960_write_ind(priv, UB960_IND_TARGET_RX_ANA(nport), 0x27, 0x0, NULL); + 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, - NULL); + &ret); /* set serdes_driver_mode into FPD IV mode */ ub960_write_ind(priv, UB960_IND_TARGET_RX_ANA(nport), 0x04, 0x00, - NULL); + &ret); /* set FPD PBC drv into FPD IV mode */ ub960_write_ind(priv, UB960_IND_TARGET_RX_ANA(nport), 0x1b, 0x00, - NULL); + &ret); /* set serdes_system_init to 0x2f */ ub960_write_ind(priv, UB960_IND_TARGET_RX_ANA(nport), 0x21, 0x2f, - NULL); + &ret); /* set serdes_system_rst in reset mode */ ub960_write_ind(priv, UB960_IND_TARGET_RX_ANA(nport), 0x25, 0xc1, - NULL); + &ret); /* RX port to 7.55G mode */ ub960_update_bits(priv, UB960_SR_FPD_RATE_CFG, 0x3 << (nport * 2), - 0 << (nport * 2), NULL); + 0 << (nport * 2), &ret); + + if (ret) + return ret; - ub960_init_rx_port_ub9702_fpd4_aeq(priv, rxport); + ret = ub960_init_rx_port_ub9702_fpd4_aeq(priv, rxport); + if (ret) + return ret; + + return 0; } -static void ub960_init_rx_port_ub9702(struct ub960_data *priv, - struct ub960_rxport *rxport) +static int ub960_init_rx_port_ub9702(struct ub960_data *priv, + struct ub960_rxport *rxport) { unsigned int nport = rxport->nport; + int ret; if (rxport->cdr_mode == RXPORT_CDR_FPD3) - ub960_init_rx_port_ub9702_fpd3(priv, rxport); + ret = ub960_init_rx_port_ub9702_fpd3(priv, rxport); else /* RXPORT_CDR_FPD4 */ - ub960_init_rx_port_ub9702_fpd4(priv, rxport); + ret = ub960_init_rx_port_ub9702_fpd4(priv, rxport); + + if (ret) + return ret; switch (rxport->rx_mode) { case RXPORT_MODE_RAW10: @@ -2250,14 +2346,14 @@ 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, NULL); + 0x3 << 6, 0x2 << 6, &ret); break; case RXPORT_MODE_RAW12_HF: case RXPORT_MODE_RAW12_LF: /* Not implemented */ - return; + return -EINVAL; case RXPORT_MODE_CSI2_SYNC: case RXPORT_MODE_CSI2_NONSYNC: @@ -2267,30 +2363,32 @@ 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, NULL); + rxport->lv_fv_pol, &ret); /* Enable all interrupt sources from this port */ - ub960_rxport_write(priv, nport, UB960_RR_PORT_ICR_HI, 0x07, NULL); - ub960_rxport_write(priv, nport, UB960_RR_PORT_ICR_LO, 0x7f, NULL); + ub960_rxport_write(priv, nport, UB960_RR_PORT_ICR_HI, 0x07, &ret); + ub960_rxport_write(priv, nport, UB960_RR_PORT_ICR_LO, 0x7f, &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, NULL); + UB960_RR_BCC_CONFIG_I2C_PASS_THROUGH, &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, NULL); + rxport->ser.alias << 1, &ret); /* Enable RX port */ ub960_update_bits(priv, UB960_SR_RX_PORT_CTL, BIT(nport), BIT(nport), - NULL); + &ret); if (rxport->cdr_mode == RXPORT_CDR_FPD4) { /* unreset 960 AEQ */ ub960_write_ind(priv, UB960_IND_TARGET_RX_ANA(nport), 0x25, - 0x41, NULL); + 0x41, &ret); } + + return ret; } static int ub960_init_rx_ports(struct ub960_data *priv) @@ -2299,20 +2397,24 @@ static int ub960_init_rx_ports(struct ub960_data *priv) for (nport = 0; nport < priv->hw_data->num_rxports; nport++) { struct ub960_rxport *rxport = priv->rxports[nport]; + int ret; if (!rxport) continue; if (priv->hw_data->is_ub9702) - ub960_init_rx_port_ub9702(priv, rxport); + ret = ub960_init_rx_port_ub9702(priv, rxport); else - ub960_init_rx_port_ub960(priv, rxport); + ret = ub960_init_rx_port_ub960(priv, rxport); + + if (ret) + return ret; } return 0; } -static void ub960_rxport_handle_events(struct ub960_data *priv, u8 nport) +static int ub960_rxport_handle_events(struct ub960_data *priv, u8 nport) { struct device *dev = &priv->client->dev; u8 rx_port_sts1; @@ -2322,21 +2424,15 @@ static void ub960_rxport_handle_events(struct ub960_data *priv, u8 nport) int ret = 0; /* Read interrupts (also clears most of them) */ - if (!ret) - ret = ub960_rxport_read(priv, nport, UB960_RR_RX_PORT_STS1, - &rx_port_sts1, NULL); - if (!ret) - ret = ub960_rxport_read(priv, nport, UB960_RR_RX_PORT_STS2, - &rx_port_sts2, NULL); - if (!ret) - ret = ub960_rxport_read(priv, nport, UB960_RR_CSI_RX_STS, - &csi_rx_sts, NULL); - if (!ret) - ret = ub960_rxport_read(priv, nport, UB960_RR_BCC_STATUS, - &bcc_sts, NULL); + ub960_rxport_read(priv, nport, UB960_RR_RX_PORT_STS1, &rx_port_sts1, + &ret); + ub960_rxport_read(priv, nport, UB960_RR_RX_PORT_STS2, &rx_port_sts2, + &ret); + ub960_rxport_read(priv, nport, UB960_RR_CSI_RX_STS, &csi_rx_sts, &ret); + ub960_rxport_read(priv, nport, UB960_RR_BCC_STATUS, &bcc_sts, &ret); if (ret) - return; + return ret; if (rx_port_sts1 & UB960_RR_RX_PORT_STS1_PARITY_ERROR) { u16 v; @@ -2431,6 +2527,8 @@ static void ub960_rxport_handle_events(struct ub960_data *priv, u8 nport) "stable freq" : "unstable freq"); } + + return 0; } /* ----------------------------------------------------------------------------- @@ -2486,14 +2584,14 @@ static int ub960_enable_tx_port(struct ub960_data *priv, unsigned int nport) UB960_TR_CSI_CTL_CSI_ENABLE, NULL); } -static void ub960_disable_tx_port(struct ub960_data *priv, unsigned int nport) +static int ub960_disable_tx_port(struct ub960_data *priv, unsigned int nport) { struct device *dev = &priv->client->dev; 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, NULL); + return ub960_txport_update_bits(priv, nport, UB960_TR_CSI_CTL, + UB960_TR_CSI_CTL_CSI_ENABLE, 0, NULL); } static int ub960_enable_rx_port(struct ub960_data *priv, unsigned int nport) @@ -2507,16 +2605,16 @@ static int ub960_enable_rx_port(struct ub960_data *priv, unsigned int nport) UB960_SR_FWD_CTL1_PORT_DIS(nport), 0, NULL); } -static void ub960_disable_rx_port(struct ub960_data *priv, unsigned int nport) +static int ub960_disable_rx_port(struct ub960_data *priv, unsigned int nport) { struct device *dev = &priv->client->dev; dev_dbg(dev, "disable RX port %u\n", 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), NULL); + return ub960_update_bits(priv, UB960_SR_FWD_CTL1, + UB960_SR_FWD_CTL1_PORT_DIS(nport), + UB960_SR_FWD_CTL1_PORT_DIS(nport), NULL); } /* @@ -2658,12 +2756,12 @@ static int ub960_configure_ports_for_streaming(struct ub960_data *priv, 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), - NULL); + &ret); 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, NULL); + rx_data[nport].meta_dt, &ret); break; @@ -2681,7 +2779,7 @@ static int ub960_configure_ports_for_streaming(struct ub960_data *priv, (vc << UB960_RR_CSI_VC_MAP_SHIFT(2)) | (vc << UB960_RR_CSI_VC_MAP_SHIFT(1)) | (vc << UB960_RR_CSI_VC_MAP_SHIFT(0)), - NULL); + &ret); } else { unsigned int i; @@ -2690,7 +2788,7 @@ static int ub960_configure_ports_for_streaming(struct ub960_data *priv, ub960_rxport_write(priv, nport, UB960_RR_VC_ID_MAP(i), (nport << 4) | nport, - NULL); + &ret); } break; @@ -2702,9 +2800,9 @@ 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, NULL); + ub960_write(priv, UB960_SR_FWD_CTL1, fwd_ctl, &ret); - return 0; + return ret; } static void ub960_update_streaming_status(struct ub960_data *priv) @@ -3107,8 +3205,8 @@ static const struct v4l2_subdev_pad_ops ub960_pad_ops = { .set_fmt = ub960_set_fmt, }; -static void ub960_log_status_ub960_sp_eq(struct ub960_data *priv, - unsigned int nport) +static int ub960_log_status_ub960_sp_eq(struct ub960_data *priv, + unsigned int nport) { struct device *dev = &priv->client->dev; u8 eq_level; @@ -3120,7 +3218,7 @@ static void ub960_log_status_ub960_sp_eq(struct ub960_data *priv, ret = ub960_read(priv, UB960_XR_AEQ_CTL1, &v, NULL); if (ret) - return; + return ret; dev_info(dev, "\t%s strobe\n", (v & UB960_XR_AEQ_CTL1_AEQ_SFILTER_EN) ? "Adaptive" : @@ -3129,7 +3227,7 @@ static void ub960_log_status_ub960_sp_eq(struct ub960_data *priv, if (v & UB960_XR_AEQ_CTL1_AEQ_SFILTER_EN) { ret = ub960_read(priv, UB960_XR_SFILTER_CFG, &v, NULL); if (ret) - return; + return ret; dev_info(dev, "\tStrobe range [%d, %d]\n", ((v >> UB960_XR_SFILTER_CFG_SFILTER_MIN_SHIFT) & 0xf) - 7, @@ -3138,7 +3236,7 @@ static void ub960_log_status_ub960_sp_eq(struct ub960_data *priv, ret = ub960_rxport_get_strobe_pos(priv, nport, &strobe_pos); if (ret) - return; + return ret; dev_info(dev, "\tStrobe pos %d\n", strobe_pos); @@ -3146,7 +3244,7 @@ static void ub960_log_status_ub960_sp_eq(struct ub960_data *priv, ret = ub960_rxport_read(priv, nport, UB960_RR_AEQ_BYPASS, &v, NULL); if (ret) - return; + return ret; dev_info(dev, "\t%s EQ\n", (v & UB960_RR_AEQ_BYPASS_ENABLE) ? "Manual" : @@ -3156,15 +3254,20 @@ static void ub960_log_status_ub960_sp_eq(struct ub960_data *priv, ret = ub960_rxport_read(priv, nport, UB960_RR_AEQ_MIN_MAX, &v, NULL); if (ret) - return; + return ret; dev_info(dev, "\tEQ range [%u, %u]\n", (v >> UB960_RR_AEQ_MIN_MAX_AEQ_FLOOR_SHIFT) & 0xf, (v >> UB960_RR_AEQ_MIN_MAX_AEQ_MAX_SHIFT) & 0xf); } - if (ub960_rxport_get_eq_level(priv, nport, &eq_level) == 0) - dev_info(dev, "\tEQ level %u\n", eq_level); + ret = ub960_rxport_get_eq_level(priv, nport, &eq_level); + if (ret) + return ret; + + dev_info(dev, "\tEQ level %u\n", eq_level); + + return 0; } static int ub960_log_status(struct v4l2_subdev *sd) @@ -3176,11 +3279,15 @@ static int ub960_log_status(struct v4l2_subdev *sd) u16 v16 = 0; u8 v = 0; u8 id[UB960_SR_FPD3_RX_ID_LEN]; + int ret = 0; 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], NULL); + for (unsigned int i = 0; i < sizeof(id); i++) { + ret = ub960_read(priv, UB960_SR_FPD3_RX_ID(i), &id[i], NULL); + if (ret) + return ret; + } dev_info(dev, "ID '%.*s'\n", (int)sizeof(id), id); @@ -3194,24 +3301,39 @@ static int ub960_log_status(struct v4l2_subdev *sd) continue; } - ub960_txport_read(priv, nport, UB960_TR_CSI_STS, &v, NULL); + ret = ub960_txport_read(priv, nport, UB960_TR_CSI_STS, &v, NULL); + if (ret) + return ret; + 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, - NULL); + ret = ub960_read16(priv, UB960_SR_CSI_FRAME_COUNT_HI(nport), + &v16, NULL); + if (ret) + return ret; + dev_info(dev, "\tframe counter %u\n", v16); - ub960_read16(priv, UB960_SR_CSI_FRAME_ERR_COUNT_HI(nport), - &v16, NULL); + ret = ub960_read16(priv, UB960_SR_CSI_FRAME_ERR_COUNT_HI(nport), + &v16, NULL); + if (ret) + return ret; + dev_info(dev, "\tframe error counter %u\n", v16); - ub960_read16(priv, UB960_SR_CSI_LINE_COUNT_HI(nport), &v16, - NULL); + ret = ub960_read16(priv, UB960_SR_CSI_LINE_COUNT_HI(nport), + &v16, NULL); + if (ret) + return ret; + dev_info(dev, "\tline counter %u\n", v16); - ub960_read16(priv, UB960_SR_CSI_LINE_ERR_COUNT_HI(nport), - &v16, NULL); + ret = ub960_read16(priv, UB960_SR_CSI_LINE_ERR_COUNT_HI(nport), + &v16, NULL); + if (ret) + return ret; + dev_info(dev, "\tline error counter %u\n", v16); } @@ -3225,8 +3347,10 @@ static int ub960_log_status(struct v4l2_subdev *sd) continue; } - ub960_rxport_read(priv, nport, UB960_RR_RX_PORT_STS1, &v, - NULL); + ret = ub960_rxport_read(priv, nport, UB960_RR_RX_PORT_STS1, &v, + NULL); + if (ret) + return ret; if (v & UB960_RR_RX_PORT_STS1_LOCK_STS) dev_info(dev, "\tLocked\n"); @@ -3234,32 +3358,53 @@ 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, - NULL); + ret = ub960_rxport_read(priv, nport, UB960_RR_RX_PORT_STS2, &v, + NULL); + if (ret) + return ret; + dev_info(dev, "\trx_port_sts2 %#02x\n", v); - ub960_rxport_read16(priv, nport, UB960_RR_RX_FREQ_HIGH, &v16, - NULL); + ret = ub960_rxport_read16(priv, nport, UB960_RR_RX_FREQ_HIGH, + &v16, NULL); + if (ret) + return ret; + 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, - NULL); + ret = ub960_rxport_read16(priv, nport, UB960_RR_RX_PAR_ERR_HI, + &v16, NULL); + if (ret) + return ret; + dev_info(dev, "\tparity errors %u\n", v16); - ub960_rxport_read16(priv, nport, UB960_RR_LINE_COUNT_HI, &v16, - NULL); + ret = ub960_rxport_read16(priv, nport, UB960_RR_LINE_COUNT_HI, + &v16, NULL); + if (ret) + return ret; + dev_info(dev, "\tlines per frame %u\n", v16); - ub960_rxport_read16(priv, nport, UB960_RR_LINE_LEN_1, &v16, - NULL); + ret = ub960_rxport_read16(priv, nport, UB960_RR_LINE_LEN_1, + &v16, NULL); + if (ret) + return ret; + dev_info(dev, "\tbytes per line %u\n", v16); - ub960_rxport_read(priv, nport, UB960_RR_CSI_ERR_COUNTER, &v, - NULL); + ret = ub960_rxport_read(priv, nport, UB960_RR_CSI_ERR_COUNTER, + &v, NULL); + if (ret) + return ret; + dev_info(dev, "\tcsi_err_counter %u\n", v); - if (!priv->hw_data->is_ub9702) - ub960_log_status_ub960_sp_eq(priv, nport); + if (!priv->hw_data->is_ub9702) { + ret = ub960_log_status_ub960_sp_eq(priv, nport); + if (ret) + return ret; + } /* GPIOs */ for (unsigned int i = 0; i < UB960_NUM_BC_GPIOS; i++) { @@ -3269,7 +3414,9 @@ 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, NULL); + ret = ub960_rxport_read(priv, nport, ctl_reg, &v, NULL); + if (ret) + return ret; dev_info(dev, "\tGPIO%u: mode %u\n", i, (v >> ctl_shift) & 0xf); @@ -3325,16 +3472,22 @@ 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++) { - if (int_sts & UB960_SR_INTERRUPT_STS_IS_CSI_TX(i)) - ub960_csi_handle_events(priv, i); + if (int_sts & UB960_SR_INTERRUPT_STS_IS_CSI_TX(i)) { + ret = ub960_csi_handle_events(priv, i); + if (ret) + return IRQ_NONE; + } } 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)) - ub960_rxport_handle_events(priv, i); + if (int_sts & UB960_SR_INTERRUPT_STS_IS_RX(i)) { + ret = ub960_rxport_handle_events(priv, i); + if (ret) + return IRQ_NONE; + } } return IRQ_HANDLED; @@ -3938,7 +4091,7 @@ static const struct regmap_config ub960_regmap_config = { .disable_locking = true, }; -static void ub960_reset(struct ub960_data *priv, bool reset_regs) +static int ub960_reset(struct ub960_data *priv, bool reset_regs) { struct device *dev = &priv->client->dev; unsigned int v; @@ -3948,7 +4101,9 @@ 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, NULL); + ret = ub960_write(priv, UB960_SR_RESET, bit, NULL); + if (ret) + return ret; mutex_lock(&priv->reg_lock); @@ -3959,6 +4114,8 @@ static void ub960_reset(struct ub960_data *priv, bool reset_regs) if (ret) dev_err(dev, "reset failed: %d\n", ret); + + return ret; } static int ub960_get_hw_resources(struct ub960_data *priv) @@ -4017,7 +4174,9 @@ static int ub960_enable_core_hw(struct ub960_data *priv) fsleep(2000); } - ub960_reset(priv, true); + ret = ub960_reset(priv, true); + if (ret) + goto err_pd_gpio; /* Runtime check register accessibility */ ret = ub960_read(priv, UB960_SR_REV_MASK, &rev_mask, NULL); @@ -4132,7 +4291,9 @@ static int ub960_probe(struct i2c_client *client) if (ret) goto err_disable_vpocs; - ub960_reset(priv, false); + ret = ub960_reset(priv, false); + if (ret) + goto err_disable_vpocs; port_mask = 0; @@ -4159,7 +4320,9 @@ static int ub960_probe(struct i2c_client *client) * Clear any errors caused by switching the RX port settings while * probing. */ - ub960_clear_rx_errors(priv); + ret = ub960_clear_rx_errors(priv); + if (ret) + goto err_disable_vpocs; ret = ub960_init_atr(priv); if (ret) From patchwork Fri Jan 10 09:14:05 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tomi Valkeinen X-Patchwork-Id: 13934027 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 D433A209F57; Fri, 10 Jan 2025 09:15:21 +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=1736500523; cv=none; b=JN6Tm0Z+OlM0RIPMDyly2fzsxemvOPGUNBimXhJBsHQX4FTPeBwcCIBAxB2adSLb40qmpoaTUMjqT3+bFdN5E7UdJvdKvdoUrtzndROylJj9eznDkrfc2yydlZDOubToEEbNeouOPP3XN2N1/x7ecO4aBsZ0UaTwEX/ZM863joc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1736500523; c=relaxed/simple; bh=oU3ePgr/rIaYG1LxgNeQUpAlpKSeD1foBMdXF/ULxtI=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=MxwBEK5yAn/50V2mO/Ze4ygBzzOOomS0Gca2fh951kbm8aPBHGBqI0f57d+i6aII1T0pV5prWv5B2BplaP78IHqydo9fu1PSwOtxiD1rOInokDLit39Zq36S7CkKVVFT2hoxXl/9x38lBcKL2T1wjbgxrjXEaKPlJprgNq5kVok= 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=jKBI3ICT; 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="jKBI3ICT" Received: from [127.0.1.1] (91-158-153-178.elisa-laajakaista.fi [91.158.153.178]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 3F77EB63; Fri, 10 Jan 2025 10:14:13 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1736500453; bh=oU3ePgr/rIaYG1LxgNeQUpAlpKSeD1foBMdXF/ULxtI=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=jKBI3ICTFlt0ZMnTjO7ytqc09dgwEygzVUlC1OHrBJoU2Fpy5Htqm7vWPl1K6iaP0 Ds+KLFKW2yQ7bksPecAZhfXNH31nW50UvI/JDmODGZpUreE3GDqwaRnyKAOWL6uG6f h+ebX6Gj6tlMZenzX7wUX5pvPCQ9JZ/Er62DTxr0= From: Tomi Valkeinen Date: Fri, 10 Jan 2025 11:14:05 +0200 Subject: [PATCH 05/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: <20250110-ub9xx-improvements-v1-5-e0b9a1f644da@ideasonboard.com> References: <20250110-ub9xx-improvements-v1-0-e0b9a1f644da@ideasonboard.com> In-Reply-To: <20250110-ub9xx-improvements-v1-0-e0b9a1f644da@ideasonboard.com> To: Mauro Carvalho Chehab Cc: linux-media@vger.kernel.org, linux-kernel@vger.kernel.org, Devarsh Thakkar , Jai Luthra , Sakari Ailus , Tomi Valkeinen X-Mailer: b4 0.13.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=4173; i=tomi.valkeinen@ideasonboard.com; h=from:subject:message-id; bh=oU3ePgr/rIaYG1LxgNeQUpAlpKSeD1foBMdXF/ULxtI=; b=owEBbQKS/ZANAwAIAfo9qoy8lh71AcsmYgBngOUSeMSjoQKitI8C8qh17ev8ak34QRB9TJOI8 rXZYlWxEyOJAjMEAAEIAB0WIQTEOAw+ll79gQef86f6PaqMvJYe9QUCZ4DlEgAKCRD6PaqMvJYe 9ZEhD/9GDL+jNW8bgCkR/WvlU3l7nBC5Zm/R2PMn90JCvjPjMVU2SmFyemdiNssFxvvefc2vE+n 4CC6A/UbanDyrEijruz+7WqQB5RPeW5dpmboCPad6vgh4cRKMjk5VWOCKSi5GK5Qg95Y0oVtC1I WNLgYaUJOg02BHKxrMB1gXcvoX1e8j4rlqlte4fUhFPaxAYqi62X/1ZD28OY6mMWOEFULkshq9q an1E3YbQrOGaTVPLvUhWTE9ABeLQkMUxZn0YtSoyTrJEtck1iPP/r7VJPMALEU+CUTCT/jJ5YAA +k4SLxJRqp3gy93FnGwkNhbe+5O3G11Qz/71f6THtD2haPR7ygP7EV8eu9dw5it2Z3MhcuL2XiB yiwu2nF+tOzccmOuOameRvNpn7x5ubkpgd+OJkvf+5gYAo7V+O43uqj38YFiYx+84EcaFozhZ6Q /siW1hmfphfZA8BF6b+rgaqoCSJ0We7eLHsMn1SAmmfXA/ezcBz9FTH3o4HEnIT1zs0ITAO00Vk LSeLtSn1aX1ET4joQH+5/79guSL7VrAQUyGfLfBr7Tr+FB8imR0ggs3uvFLtYwDx+F7YgXyQD37 tSEObHk/4MIJc9WifPpZkvkmELRDRCtoyLS+rfC4dA5cglMfquVO1b3ticBdrVrc/YkxN2d2k9o tPcIxJKu82dt9cw== X-Developer-Key: i=tomi.valkeinen@ideasonboard.com; a=openpgp; fpr=C4380C3E965EFD81079FF3A7FA3DAA8CBC961EF5 Add error handling to ub953_log_status(). Signed-off-by: Tomi Valkeinen --- 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 07d451816855..99a4852b9381 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 Fri Jan 10 09:14:06 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tomi Valkeinen X-Patchwork-Id: 13934028 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 4A9C820ADE1; Fri, 10 Jan 2025 09:15:21 +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=1736500525; cv=none; b=FSp9sw8IIveY4M7dY3UvqeX60AETyk/a/0ITtGHADxH6yRncP3gcoc32VTt9v21MJQGeV+P8raOcBs06mLuBt30G43ASfOEo2MSJmfbejR6zMqH1vlYa2aLNtI5EN1654TyQN0/Z0r6cHn03RtNsUQjKECZMCUYNHrDhtEUyFKc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1736500525; c=relaxed/simple; bh=oXOtB1VaBWrBP8APSbLI3Nh6kPe3N7eP/+LzdenabzA=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=G3y9L3E6Mud4SZ/mxbVRdA4rEizAqC9aK/gB4ofWdTaVQYAxrx+rbORNnMnIF3KU8ypq44HzjawS3IbmrFJTqVcaIYsx7y2Vl8QKlD/sfM8in1f7sM5vyGz5rmJ8cjYu/2+cEUPHtu60d048ZFF+Wj1VdrlaIC2aQxq3B6+PJ4M= 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=bgpS6jiD; 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="bgpS6jiD" Received: from [127.0.1.1] (91-158-153-178.elisa-laajakaista.fi [91.158.153.178]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id C737B14A6; Fri, 10 Jan 2025 10:14:13 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1736500454; bh=oXOtB1VaBWrBP8APSbLI3Nh6kPe3N7eP/+LzdenabzA=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=bgpS6jiDvdoKW1q8nVUC7aNYg6cKHRn5UD/xki4qZShp6ZTaSWvB6Wi4XdebJAYRx F5ywBnfxUh+V4vWcGKcanWnYcaQq4khuiOSFZr3DXAwy+fJQpx3JVl/JHwuunlG2nd 9aHwuRE9PBvhSnZ24eGHxNsbGWjW+9VXQkuCvcXg= From: Tomi Valkeinen Date: Fri, 10 Jan 2025 11:14:06 +0200 Subject: [PATCH 06/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: <20250110-ub9xx-improvements-v1-6-e0b9a1f644da@ideasonboard.com> References: <20250110-ub9xx-improvements-v1-0-e0b9a1f644da@ideasonboard.com> In-Reply-To: <20250110-ub9xx-improvements-v1-0-e0b9a1f644da@ideasonboard.com> To: Mauro Carvalho Chehab Cc: linux-media@vger.kernel.org, linux-kernel@vger.kernel.org, Devarsh Thakkar , Jai Luthra , Sakari Ailus , Tomi Valkeinen X-Mailer: b4 0.13.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=2004; i=tomi.valkeinen@ideasonboard.com; h=from:subject:message-id; bh=oXOtB1VaBWrBP8APSbLI3Nh6kPe3N7eP/+LzdenabzA=; b=owEBbQKS/ZANAwAIAfo9qoy8lh71AcsmYgBngOUSGTCym3FB5u/+dbyl5OHefR3ryip6mlTn+ WWFnethRduJAjMEAAEIAB0WIQTEOAw+ll79gQef86f6PaqMvJYe9QUCZ4DlEgAKCRD6PaqMvJYe 9VQSD/99MA7q9c7/yqeN+fAk4wSUe49+1BvJe+nFLfzV0qji/tQYVtsL/2m+Chj5lJEe70eKD0Z 0KrdYZkcxAhbt726ClWSM10ZoYrv3n6jny5TLICS73+9mmub0pQvABmrZuW7ruGiRPAO9HmxSKd 8PvroMSqAljU8M341Lc8a38SZFrcs8CKoh+k6yghVQ4Dow8lWluXRvK3aRvYMTChH0NndL/87C0 1IuVKYLDjtwlyi+4BnVxDuoGhTy/MMoPCA7CfMZM+Ssz2JIC4UXLf0+MKC5RAtXeOEQZIhTnTj2 qvwzI1ksA3LciYXvR+aCHfDQBWnTWMH4fqKwObRZvA7ThcbgTv+5qJ3PyqQ9vZ7iUaNbl07Xsfz uE0kOv6TMGezJmmcPL5lBzVy9nNmzyJeou0a4NS95VHDMJD9zgF9KFMSCMHEUYDX+Xu0uo/ihZj we7xrpK8wjdbQDvXI/EGIJ98p6tIjyz4F12N9jF6lFc4qqr7ouO4GO96IC3FX32JKXkJIbCGZQX I3yDryu5p3AZbPucemUhvOzTR5O0TSbtLk5h2OR2GGOKWPJUVmQghzp9uelAdW8cVt0HxxM+Ztj N9uvLslVv9x6nB8KjS0LBreNnT3xJ9pRtiN4PWGY6RRkfSQ/XpQ62Fi/bP3PK9LXrn3yB1ce3kT 7Gra3HK+SHmbVnw== X-Developer-Key: i=tomi.valkeinen@ideasonboard.com; a=openpgp; fpr=C4380C3E965EFD81079FF3A7FA3DAA8CBC961EF5 Add error handling to ub913_log_status(). Signed-off-by: Tomi Valkeinen --- 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 34f92aa1c56c..111166dbbce3 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 Fri Jan 10 09:14:07 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tomi Valkeinen X-Patchwork-Id: 13934029 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 F162920A5FB; Fri, 10 Jan 2025 09:15:24 +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=1736500526; cv=none; b=Smj4rH9fTbezILQ72uKR5PbogtQcwyoLdopQJWcUQmLy96mc2uzzb5nHDMIfapZoBSmbJ1uZlpNHNgJMUiK9G/hNpBlN4aGpr8g9U0P8HGdEge7evL/rvbKkFdlOvOBDU8Dlewb3MBlX00KWjzBFJDItuKjQSTnK0o1vsKRGwgM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1736500526; c=relaxed/simple; bh=p8Bj8Thaw/dlePmOBdZcBbm5AP9EbnHTYCi+x/1ar6s=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Ttk+p8cWE9rVHJh1j/Ws9jt9MW+u1BMe86f7KhB9xFPJGchP8PQLAP3alkbBiTQHBrisOgHl9E8+ukC5iOlNlbDyWlPjtXFE0Itz5vl1qCAHn3XegKVGTjovZ1yqV9JbYDQbvGf9fh1JQz/4OffnvKBBlr5TQ1PCMbx/h8J0lFE= 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=sNW/B5Df; 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="sNW/B5Df" Received: from [127.0.1.1] (91-158-153-178.elisa-laajakaista.fi [91.158.153.178]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 548171624; Fri, 10 Jan 2025 10:14:14 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1736500454; bh=p8Bj8Thaw/dlePmOBdZcBbm5AP9EbnHTYCi+x/1ar6s=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=sNW/B5DfVsxPIlWs/gbDaOOxgTQIqNtndBMRrhhqWUD8dYBTiZIZpNSsIOyCVCOQO uADsh07yPOZWPSjMJ9gR0N3/WNCQInCL5fHasihmZ30ofpSJY6obPRB/5gyFOSPBNG NPkDbw2zhmiNs7AysDTn55g/cqSmFqG4B/oYT8UU= From: Tomi Valkeinen Date: Fri, 10 Jan 2025 11:14:07 +0200 Subject: [PATCH 07/19] media: i2c: ds90ub953: Speed-up I2C watchdog timer Precedence: bulk X-Mailing-List: linux-media@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20250110-ub9xx-improvements-v1-7-e0b9a1f644da@ideasonboard.com> References: <20250110-ub9xx-improvements-v1-0-e0b9a1f644da@ideasonboard.com> In-Reply-To: <20250110-ub9xx-improvements-v1-0-e0b9a1f644da@ideasonboard.com> To: Mauro Carvalho Chehab Cc: linux-media@vger.kernel.org, linux-kernel@vger.kernel.org, Devarsh Thakkar , Jai Luthra , Sakari Ailus , Tomi Valkeinen X-Mailer: b4 0.13.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=1338; i=tomi.valkeinen@ideasonboard.com; h=from:subject:message-id; bh=dJ8Ay7yVp08Tnuu7iFHmWAeN4NOSMAkgHjh6Cw+88WE=; b=owEBbQKS/ZANAwAIAfo9qoy8lh71AcsmYgBngOUS4WBAO/hSAnDZ2LE77PqklVNfLRurmeoVR ZA8t/z+8vuJAjMEAAEIAB0WIQTEOAw+ll79gQef86f6PaqMvJYe9QUCZ4DlEgAKCRD6PaqMvJYe 9fv+D/0QVOa8We2WZqUExanJH7qxVr/sh8QiUGcKln+rojpbwWW7mUbJq38+TMWqNUJUfRdI5jI dFJ5/zRSicvw50YN8/PJZlooLO6rZuLBSrMRwcympNblfdOyPpFHGjiXSbl6dzUk+bjLMgNH+ac eLebJuh3Tj5DSJr4yD3PO2PeZ+4ANBvkXQw54hvZw764fR2GZenS2UoCt5F6YmNTTSjmdypk7Dm ATuZgXgtYb2WmTauuNUpqqOU3zrIw5SkBpe9w0ur2IGjmS72HZ+HLzAhlUMkJ0oHnb1Xj3oK6A0 0Ij0eJztYXm7c9i0vxsWTG4usWFJy8Bsx8PksXbOmR/q2Q87plrInssM1pOWCjKAmmMcTMztwnV MsXyY1ydYur/ZMZKTMhETBxr/udS2BgUJ8SQE9zwneZlkL4HbkHvBWTlAmg6dPvimf27BBxv0Y1 IxFC/QiG3L6vxzenvdgXGdV3kvZjQxKfDwp8jKYGWExB8vwjePeBozyFwfRrNT1j5eDpeZ4D5re NOspPyGft/qYSExut6r0FLyVdRoFf+cqST9uxSHq8LS6g5rE8dLzmkWrJ5Hrrc+toYMYG8IoD/B V936QvOcY5/7f+FMog4hRjw2MT00yOCoLpTiLCg9lVIwgNDruJ8rShUut9OVm+gzHNQ0p61o8Vs BFfmodCZpKsSGaw== X-Developer-Key: i=tomi.valkeinen@ideasonboard.com; a=openpgp; fpr=C4380C3E965EFD81079FF3A7FA3DAA8CBC961EF5 From: Jai Luthra On the I2C bus for remote clients (sensors), by default the watchdog timer expires in 1s. To allow for a quicker system bring-up time, TI recommends to speed it up to 50us [1]. [1]: Section 7.3.1.1 - https://www.ti.com/lit/gpn/ds90ub953-q1 Signed-off-by: Jai Luthra Signed-off-by: Tomi Valkeinen --- drivers/media/i2c/ds90ub953.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/drivers/media/i2c/ds90ub953.c b/drivers/media/i2c/ds90ub953.c index 99a4852b9381..6c36980e8beb 100644 --- a/drivers/media/i2c/ds90ub953.c +++ b/drivers/media/i2c/ds90ub953.c @@ -54,6 +54,10 @@ #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 @@ -1320,6 +1324,13 @@ static int ub953_hw_init(struct ub953_data *priv) if (ret) return ret; + v = 0; + v |= 1 << UB953_REG_I2C_CONTROL2_SDA_OUTPUT_SETUP_SHIFT; + v |= UB953_REG_I2C_CONTROL2_BUS_SPEEDUP; + ret = ub953_write(priv, UB953_REG_I2C_CONTROL2, v, NULL); + if (ret) + return ret; + return 0; } From patchwork Fri Jan 10 09:14:08 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tomi Valkeinen X-Patchwork-Id: 13934030 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 803F520B206; Fri, 10 Jan 2025 09:15: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=1736500528; cv=none; b=pNc4LWHL6WzbVomjsQmIJEqSFjgKMZCGXEm68Y/wQLIcsFpupBikKJrhvD1CPKN2Yh2bBS9DoiFGIG4dqALrZVYm1oe2ZF1PqG//nDm1ugZZtbwpyH8a87lvNP0APfzcNSQVMZuRJoYV0NYLXaPlPGMB1MRNYdfkiBQDm9ZzfoI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1736500528; c=relaxed/simple; bh=9w53JRzipGP+au25XsPTfPMAU6safvRB3WSOdZV+WiY=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Rxld73BDUd2WrHldNT8efOd39s8z6E65x9EmV/KT7fs48FOaCXtDA8w+UnVgyYtjbrMXbyeflbShqn6RQ9ZVTb3QmRJtGWVXIjEbadkQrLmu33oamEntMezGrNdBWRtM8yhd+EQDtQdq3qFUxJbLyb8gMxWjBbp5/aVSrk3d0AE= 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=JodxH9VM; 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="JodxH9VM" Received: from [127.0.1.1] (91-158-153-178.elisa-laajakaista.fi [91.158.153.178]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id D8D471971; Fri, 10 Jan 2025 10:14:14 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1736500455; bh=9w53JRzipGP+au25XsPTfPMAU6safvRB3WSOdZV+WiY=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=JodxH9VMZMTa58nYzTMkj8ZpGar/zip2Yt38YejSgONHWyskXEAefLIzbjgtoknZu 3Qg61DCtXcjVwdxVmBlyLVkFAtQPiD5U8mti3tupEDXi+9Q+ijibHywsxhaW3y/8tD fdBeCFbv42pxM2dx45wxTSr9C/XmyBbD335GXKEA= From: Tomi Valkeinen Date: Fri, 10 Jan 2025 11:14:08 +0200 Subject: [PATCH 08/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: <20250110-ub9xx-improvements-v1-8-e0b9a1f644da@ideasonboard.com> References: <20250110-ub9xx-improvements-v1-0-e0b9a1f644da@ideasonboard.com> In-Reply-To: <20250110-ub9xx-improvements-v1-0-e0b9a1f644da@ideasonboard.com> To: Mauro Carvalho Chehab Cc: linux-media@vger.kernel.org, linux-kernel@vger.kernel.org, Devarsh Thakkar , Jai Luthra , Sakari Ailus , Tomi Valkeinen X-Mailer: b4 0.13.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=4300; i=tomi.valkeinen@ideasonboard.com; h=from:subject:message-id; bh=9w53JRzipGP+au25XsPTfPMAU6safvRB3WSOdZV+WiY=; b=owEBbQKS/ZANAwAIAfo9qoy8lh71AcsmYgBngOUTBujd3qdE65AkKVZaLHzhmdVEMBsUowxXM 6UmkwN6jRGJAjMEAAEIAB0WIQTEOAw+ll79gQef86f6PaqMvJYe9QUCZ4DlEwAKCRD6PaqMvJYe 9ZkpD/0bUqwgCGUsUvKmGM+34PwqIJ6CV4qKv2Qt9oPgCDGzGKZ2wvgtrV3go/685Z3TYsfCV18 EmLfeg7tI8f6o9VeO76pjARtDVPMhzq3aIjkGLqosfHw0ajhFbLS7uXH81xdjVv19b5PS4PDNZG b3W2cim5V0aOyd5f0WwawOjvbSfk0FoTnJaoYU43fLjN8vtK+nEUo84ZwduhXKy58yrWjoulUwV LymHE+efw0dgc+FlvtWnIb2ByX2uy8jIm1viRpBRAxX6SksAJCTKJmw7kdN5FaMuquuRAIZLzak tBtQefwpWYuAp6fzE8GgMu482GaxqEDVEAO7xbYXih8SqQNO8eEwBmLB/e9xs+Ai4Q39a+HhqnI vgP7plPgj9BCoFNf/Py/QHgiel1TaJLoZXuw/xZWfCsvgnVbn7QgcsYZ0LXsrzooDUIRKbHUucS Dx9naTBbbN0+7gHrCKGXKRTrlEPup/ZckLBiTBtYiKAz/kXdkSrfYEYXcG2wGavHiSeSDxzG44p n2M07jfbDCj5njDMay8fuNJg/9R+c3/8w/b2LhyfSvEzKI5tjWPNEXUx2N/zuCdSsHxLiGZMPDj RaQwKMgSE5rvHfvZp5WUyp/qLbVRtPj4ZEVkrC/21vx8rRkEX+Kzlzpc8nQm09NF2YwCWB0V8YT K47k+OkQD4iyMMQ== X-Developer-Key: i=tomi.valkeinen@ideasonboard.com; a=openpgp; fpr=C4380C3E965EFD81079FF3A7FA3DAA8CBC961EF5 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 --- 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 80bbba0792c1..fc910d13d7db 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 Fri Jan 10 09:14:09 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tomi Valkeinen X-Patchwork-Id: 13934031 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 4DFAA20B804; Fri, 10 Jan 2025 09:15:28 +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=1736500529; cv=none; b=Z1i+Td63UEwBxMlr8mX9cfH8FFZueBZbEPJ1I+r7AcIHOP3n4/kk0xU/XV2CunBttjtF3PB8udHJJLlfk2Z35rXMStxFoDqn8cclkTWV0PeyFjmBeuAZZVXMRw5JB/AGEt9XC911UA0sB33eNXQt1rmkVYeW8N/0i9jJV+a/M3s= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1736500529; c=relaxed/simple; bh=LqsWKWLvcjKl8miOWsCgojhD6f1dXEtfdcZMlaaNP+4=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=CvYWF7U3ttZV9pXl9gCcHfk8yKxw3GS626DErfm2KygzGAP7VAFHxjRB00DMZ18WVebABU0Ja9SCxpbVUfenGK2SNQeTFueGD4/ZNuKFGqoxOqlnnAKz+FoMzUBOFfnZ297P/+a72H5mTV92/kBkFHU62gyUDEneQgRZF0C3CvU= 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=R1/um2UO; 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="R1/um2UO" Received: from [127.0.1.1] (91-158-153-178.elisa-laajakaista.fi [91.158.153.178]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 6883F1AA2; Fri, 10 Jan 2025 10:14:15 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1736500455; bh=LqsWKWLvcjKl8miOWsCgojhD6f1dXEtfdcZMlaaNP+4=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=R1/um2UO60x8MEx+ko4vbopj/UBOIfslJFb0EUgnS+oohE949n1fVnBjvtI4ruqJV o2P5RcLjSMBC9/wmQJxjbazcHOob9RK784qyjldYTBLKKuTfoZvs644Lw4IkxN81b5 d2FDFSTVPidxeilskadpJYoMEwnAB6Rx9JpfzzAQ= From: Tomi Valkeinen Date: Fri, 10 Jan 2025 11:14:09 +0200 Subject: [PATCH 09/19] media: i2c: ds90ub960: Add UB9702 specific registers Precedence: bulk X-Mailing-List: linux-media@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20250110-ub9xx-improvements-v1-9-e0b9a1f644da@ideasonboard.com> References: <20250110-ub9xx-improvements-v1-0-e0b9a1f644da@ideasonboard.com> In-Reply-To: <20250110-ub9xx-improvements-v1-0-e0b9a1f644da@ideasonboard.com> To: Mauro Carvalho Chehab Cc: linux-media@vger.kernel.org, linux-kernel@vger.kernel.org, Devarsh Thakkar , Jai Luthra , Sakari Ailus , Tomi Valkeinen X-Mailer: b4 0.13.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=2258; i=tomi.valkeinen@ideasonboard.com; h=from:subject:message-id; bh=LqsWKWLvcjKl8miOWsCgojhD6f1dXEtfdcZMlaaNP+4=; b=owEBbQKS/ZANAwAIAfo9qoy8lh71AcsmYgBngOUTvX5jG2zGkVxu7XXHlXLlfvHrJbZcJEsnn NsMaTanZGOJAjMEAAEIAB0WIQTEOAw+ll79gQef86f6PaqMvJYe9QUCZ4DlEwAKCRD6PaqMvJYe 9YecD/wMKXtAX0Ml8FHRhQKXgNIqW7oHnBN5k4trkA49mXX4sI095YtGhYLoyQhVuDD4waKEMHS 7ohtldMmLPBWVYQsRUeoxO6+44Ku0YtuubaKWq0EXa5VQQNGitQul7b8jCcEe2QVtC+18fQsWs8 +RytaYz3/oQkkGjnaHqo0aKLdpy3Yq5kut4sr81iEGX5Q/z08Umr7u82PExy74ndhPhogqVfT2/ 5wOgfnzFHBFPsvTOg3lKp5X9qCtfRZi04rIq2MuhdVNl7djW/644ZPlw4EMqhT6AgAOkN0tZUvZ 7yyTJAbzVLG6lxhOe/ha2761r/PBmEuMblptI1hoo3gAnj9lm7ap5WyA3UpDAD47RelI/6Px5hq QAOoo9WornwV1jjPIJS2Nls4gzkc5WQY6+UY9opjt/lBSO/+Xo2IW0IC632jR9IbawgZSI3DnWt HXZG/mj+4a8t8C6rs7td4cIz8GKYWW8S8PWz5EP/fknfgJmNFDkEfsDo84t0cvjfjEBf5POaOcJ x9M2XJsVZaIyoABCNg32QKfQ1++JDIjEoGdW0zQgShRJ71BZaq+cnsHREFv5gvkf3/BvZoT1KHT aVP2ajVZ0NMAhtyx7/N17DI1WnQGCqsII2ad1A27f2Ur2ilqjqDomAOfSGbzANq4UdTEJsBSkd7 ueQgx0zpIUfn5Hg== X-Developer-Key: i=tomi.valkeinen@ideasonboard.com; a=openpgp; fpr=C4380C3E965EFD81079FF3A7FA3DAA8CBC961EF5 Add UB9702 specific registers which will be used in the following patches. Signed-off-by: Tomi Valkeinen --- drivers/media/i2c/ds90ub960.c | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/drivers/media/i2c/ds90ub960.c b/drivers/media/i2c/ds90ub960.c index fc910d13d7db..a890097ad105 100644 --- a/drivers/media/i2c/ds90ub960.c +++ b/drivers/media/i2c/ds90ub960.c @@ -391,12 +391,47 @@ /* UB9702 Registers */ +#define UB9702_SR_CSI_EXCLUSIVE_FWD2 0x3c #define UB9702_SR_REFCLK_FREQ 0x3d +#define UB9702_RR_RX_CTL_1 0x80 +#define UB9702_RR_RX_CTL_2 0x87 #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_RX_SM_SEL_2 0xd4 #define UB9702_RR_CHANNEL_MODE 0xe4 +#define UB9702_IND_TARGET_SAR_ADC 0x0a + +#define UB9702_IR_RX_ANA_FPD_BC_CTL0 0x04 +#define UB9702_IR_RX_ANA_FPD_BC_CTL1 0x0d +#define UB9702_IR_RX_ANA_FPD_BC_CTL2 0x1b +#define UB9702_IR_RX_ANA_SYSTEM_INIT_REG0 0x21 +#define UB9702_IR_RX_ANA_AEQ_ALP_SEL6 0x27 +#define UB9702_IR_RX_ANA_AEQ_ALP_SEL7 0x28 +#define UB9702_IR_RX_ANA_AEQ_ALP_SEL10 0x2b +#define UB9702_IR_RX_ANA_AEQ_ALP_SEL11 0x2c +#define UB9702_IR_RX_ANA_EQ_ADAPT_CTRL 0x2e +#define UB9702_IR_RX_ANA_AEQ_CFG_1 0x34 +#define UB9702_IR_RX_ANA_AEQ_CFG_2 0x4d +#define UB9702_IR_RX_ANA_GAIN_CTRL_0 0x71 +#define UB9702_IR_RX_ANA_GAIN_CTRL_0 0x71 +#define UB9702_IR_RX_ANA_VGA_CTRL_SEL_1 0x72 +#define UB9702_IR_RX_ANA_VGA_CTRL_SEL_2 0x73 +#define UB9702_IR_RX_ANA_VGA_CTRL_SEL_3 0x74 +#define UB9702_IR_RX_ANA_VGA_CTRL_SEL_6 0x77 +#define UB9702_IR_RX_ANA_AEQ_CFG_3 0x79 +#define UB9702_IR_RX_ANA_AEQ_CFG_4 0x85 +#define UB9702_IR_RX_ANA_EQ_CTRL_SEL_15 0x87 +#define UB9702_IR_RX_ANA_EQ_CTRL_SEL_24 0x90 +#define UB9702_IR_RX_ANA_EQ_CTRL_SEL_38 0x9e +#define UB9702_IR_RX_ANA_FPD3_CDR_CTRL_SEL_5 0xa5 +#define UB9702_IR_RX_ANA_FPD3_AEQ_CTRL_SEL_1 0xa8 +#define UB9702_IR_RX_ANA_EQ_OVERRIDE_CTRL 0xf0 +#define UB9702_IR_RX_ANA_VGA_CTRL_SEL_8 0xf1 + +#define UB9702_IR_CSI_ANA_CSIPLL_REG_1 0x92 + /* EQ related */ #define UB960_MIN_AEQ_STROBE_POS -7 From patchwork Fri Jan 10 09:14:10 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tomi Valkeinen X-Patchwork-Id: 13934032 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 E8AE920C00D; Fri, 10 Jan 2025 09:15:29 +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=1736500531; cv=none; b=RWc9R0dTPciLEuJ9IMSEBAIAmKjhJukxAtqVOiDY4c0hoX7KTbTcozCqU/JSCbk6+LN7XVQnSu5KirO958Xq4Zxsi1HVG6bJltS9ONxmBIH0wh0dPCL4zxmo9dqOL/aZ7RJukMYC8Bc6Gxg4GWQHbvWcG1cHOAQR9FlwU/LCDZM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1736500531; c=relaxed/simple; bh=aMzTw3m2IXfT2B1cdcJzjng6lSwwJSqSBJ5aGIXCVNM=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=bg/7CFUOJkaOdPdAh0DkdSzi7evAN9Th3aH6WWzfD0f/zm0v9/dciMTuGHpSJDHQuSbgBAtlGZyXbgkEVqyztVftE3aZC/A3bGxDet4mAxNWTBPlVPjL0vMCb8RH6dGtE7n2m88nLfvdIR9cGciCcRz8EVWPZYVNKh/UFaQo6Ns= 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=TrxvQDvL; 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="TrxvQDvL" Received: from [127.0.1.1] (91-158-153-178.elisa-laajakaista.fi [91.158.153.178]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id EA9261AA6; Fri, 10 Jan 2025 10:14:15 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1736500456; bh=aMzTw3m2IXfT2B1cdcJzjng6lSwwJSqSBJ5aGIXCVNM=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=TrxvQDvLI9haji5xoLZRQGPeknVAKyQcL76R0UUM7Ec534OyESFdjD9bygjKh49k/ GwrfzidOX2DGPkcFFObQXpk9a7BKoBnmk/n62JXIRMtZvbLJPptMY/EhasJQV1Fp7d YWhnZ3gP/558VnH4A76Evaq0/HYRuURH6Ckg1Ou4= From: Tomi Valkeinen Date: Fri, 10 Jan 2025 11:14:10 +0200 Subject: [PATCH 10/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: <20250110-ub9xx-improvements-v1-10-e0b9a1f644da@ideasonboard.com> References: <20250110-ub9xx-improvements-v1-0-e0b9a1f644da@ideasonboard.com> In-Reply-To: <20250110-ub9xx-improvements-v1-0-e0b9a1f644da@ideasonboard.com> To: Mauro Carvalho Chehab Cc: linux-media@vger.kernel.org, linux-kernel@vger.kernel.org, Devarsh Thakkar , Jai Luthra , Sakari Ailus , Tomi Valkeinen X-Mailer: b4 0.13.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=3822; i=tomi.valkeinen@ideasonboard.com; h=from:subject:message-id; bh=aMzTw3m2IXfT2B1cdcJzjng6lSwwJSqSBJ5aGIXCVNM=; b=owEBbQKS/ZANAwAIAfo9qoy8lh71AcsmYgBngOUUhNp3lugxXn+vd8UqlDRYPd39ZbxwLXhEd HDCNi5/HReJAjMEAAEIAB0WIQTEOAw+ll79gQef86f6PaqMvJYe9QUCZ4DlFAAKCRD6PaqMvJYe 9SBpD/9rmYVCzlmQAWjzaUvjYKhXICqGauyyHBaUFsMTT6wsQIXNyU2NVsaOeKx5nTkafpUJjfv JhX1kJ+7rwlMiDHs1ZfFVqXCzUcyciy/kE74xEYI/YK03vK96bCenK0cALJmlRTMgYg6r/wrJjg jTqD9TuVDzCg/j+hdYwtjn2YNdjrtvI53T80Med8vnrExGEx9iZa8rEJsHuKkVcP8ztRjKv/clf fIgTFzHfNGq3oBLs8h8MTMCwMgZfADe43VvkKQjA2jvrqY0ah0QmD99Lpya7SrY/08DOaUGUwBb wksnQD1FukK02qrunC9astH51NarjxzaB+nw1apZh/kzJeGggPRzn9dlKkqyvu2vOVBhrY6VkP1 r5okiigtWwR8sByDHrZyrSgHHm7N1x7OzsVIvp32hKhDa06EbfoZ8I9xOgSQ6sWv6clmSIXWiF7 qnoORMJv6xFnnMe/k0dNoj0h4JVLq0EbkRTI1GfZ81a+ZSf6+w+mGUmWvIc52skQ7ihFjFkpqR3 dG1711j+Ma0yTaBqgmR7JA/KqA+HfjADaORGLnNUCpZBwPoSI2N1j3sfv/S671cpTiqS8TKL9sz fxPN4rrw7mtPk0Qz4glfSYcTphQv8e7QSSyjRNS95+noCssZjJMSE8KSIJzTdxmEwOZBCLpz8mz P6FgXZzaUqSsgkA== X-Developer-Key: i=tomi.valkeinen@ideasonboard.com; a=openpgp; fpr=C4380C3E965EFD81079FF3A7FA3DAA8CBC961EF5 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 --- 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 a890097ad105..3b3e756af86b 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 Fri Jan 10 09:14:11 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tomi Valkeinen X-Patchwork-Id: 13934033 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 8B5E120C460; Fri, 10 Jan 2025 09:15:31 +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=1736500533; cv=none; b=njtcDpLPJRRbiC4fyKDWvwQaIakpxdWRvw3Nu+A88PI0rezFoc2N4ot0KXo9VBbfaNGCq21XmqncjK+R3/WoQP2TiQBWYexwMGcwvH1258dphTA8M06x0L5aSfqyxuAJFZsRKaayvd89RvNTmOzOu/x5GIdYywq2ZCMlTjkGfHo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1736500533; c=relaxed/simple; bh=ZcBldV7csNp7Rh3492vSdrLLFvoKPscmdX1BHBLru6c=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=DXlY9TuXJb0m2LMVKjSO5cgM+EsF7TgcmACfUtG5DndbKqpwczfVCA9IE63K4MDIAubedUQAFvZFB3yCrAfRz6m4h4/Hd/IkePzpyLSwQoa1UzEUgIqcSCwhyZop/ru+QQmlax93cAs4slJIQd5PoNBV/49KySc5wuFYa9UjBQc= 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=pt9fbl6g; 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="pt9fbl6g" Received: from [127.0.1.1] (91-158-153-178.elisa-laajakaista.fi [91.158.153.178]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 790801D4F; Fri, 10 Jan 2025 10:14:16 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1736500456; bh=ZcBldV7csNp7Rh3492vSdrLLFvoKPscmdX1BHBLru6c=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=pt9fbl6gWmyim2kC6MyKCUzDfE17FEHI7GfEdIKwKw6TIYoZACK9/Z18WaggF5/NB zfKH/K75o1ziRCoasxlyZqrF6Pnaai6RhC2Jrg1A3Wlc2bYritkGp3a2hqc6uNj9c3 f1vGd1lQRGxCLlXEd+zzJrqLmMG1YrzgaEJVF+54= From: Tomi Valkeinen Date: Fri, 10 Jan 2025 11:14:11 +0200 Subject: [PATCH 11/19] media: i2c: ds90ub960: Refresh ub960_init_tx_ports_ub9702() Precedence: bulk X-Mailing-List: linux-media@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20250110-ub9xx-improvements-v1-11-e0b9a1f644da@ideasonboard.com> References: <20250110-ub9xx-improvements-v1-0-e0b9a1f644da@ideasonboard.com> In-Reply-To: <20250110-ub9xx-improvements-v1-0-e0b9a1f644da@ideasonboard.com> To: Mauro Carvalho Chehab Cc: linux-media@vger.kernel.org, linux-kernel@vger.kernel.org, Devarsh Thakkar , Jai Luthra , Sakari Ailus , Tomi Valkeinen X-Mailer: b4 0.13.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=2294; i=tomi.valkeinen@ideasonboard.com; h=from:subject:message-id; bh=ZcBldV7csNp7Rh3492vSdrLLFvoKPscmdX1BHBLru6c=; b=owEBbQKS/ZANAwAIAfo9qoy8lh71AcsmYgBngOUUjOYAsee6729hO9M6T+OE8gbj6Z+BfscUE 6+9dAZ5MXiJAjMEAAEIAB0WIQTEOAw+ll79gQef86f6PaqMvJYe9QUCZ4DlFAAKCRD6PaqMvJYe 9Xt+EACSau5AjV3nMm6ygT9AbGeixJDU2NQaWKJ0m2H1mhl1cWkpHFQ3o3uK7Ov30w2RoiIzgia vnD06gh627pJ42DJi8Kjzyw7ZqlXtEmRryjbQd0kzpx4NjSri9MYjuLNFNRiJA6pmjBHQcJaEDv rVIlfKgMRrkL3Inqyp1to+QDeS9pXsWen1PDaecX2jAoUmUItSsgvypXpnoS6ewIGqYaPcL/+jz IFVgt0rn2Hber8nalzNuP+p+dD+Lpgh1YRj3+8fkMtB9SCExacQaGHAQUsZCmPgNh/e3wZkDEXn nCebB6AHG2zU4r3SQxrEyEA8hy5dijMmfPcvYlbMGKh0hZNk5s/xtVEvZCQYwcN+dTLfYlXU9as 1YJzoFsr1LUDzNuRaKHrfFE+U4HjumcPlYWjlJot90ZFoMrdLJ1v0/LR7232uz2/Po/ZrFd+tTt Bz9HlK5w5TnHdxfpvZxdk3y9oTDEn9wF5B04u1cmUZGnzqV0Il1PYyzwxJDB7NKWyTgrYyAfcSH Ix9s9SxWoP5L14snfUo6UsSQjqo3YLyudajh+Nrlj4BiSUOc2NnkMr6g6CfeKfqjCFeCjuf5Osf QcAC5hYemmD2CvrHMuYf0tWoN1KTfO6wsOpLKTi7n88r7V2aNmK7gEqnVq2Q5VI8H69lkrQoYo6 TT0pf6p2T4eGBnA== X-Developer-Key: i=tomi.valkeinen@ideasonboard.com; a=openpgp; fpr=C4380C3E965EFD81079FF3A7FA3DAA8CBC961EF5 Refresh the ub960_init_tx_ports_ub9702() using the latest version of the (non-public) hardware documentation. Signed-off-by: Tomi Valkeinen --- drivers/media/i2c/ds90ub960.c | 40 +++++++++++++++++----------------------- 1 file changed, 17 insertions(+), 23 deletions(-) diff --git a/drivers/media/i2c/ds90ub960.c b/drivers/media/i2c/ds90ub960.c index 3b3e756af86b..bca858172942 100644 --- a/drivers/media/i2c/ds90ub960.c +++ b/drivers/media/i2c/ds90ub960.c @@ -2018,6 +2018,7 @@ static int ub960_init_tx_ports_ub960(struct ub960_data *priv) static int ub960_init_tx_ports_ub9702(struct ub960_data *priv) { u8 speed_select; + u8 ana_pll_div; u8 pll_div; int ret = 0; @@ -2025,47 +2026,40 @@ static int ub960_init_tx_ports_ub9702(struct ub960_data *priv) case MHZ(400): speed_select = 3; pll_div = 0x10; + ana_pll_div = 0xa2; break; case MHZ(800): speed_select = 2; pll_div = 0x10; + ana_pll_div = 0x92; break; case MHZ(1200): speed_select = 1; pll_div = 0x18; + ana_pll_div = 0x90; + break; + case MHZ(1500): + speed_select = 0; + pll_div = 0x0f; + ana_pll_div = 0x82; break; case MHZ(1600): default: speed_select = 0; pll_div = 0x10; + ana_pll_div = 0x82; + break; + case MHZ(2500): + speed_select = 0x10; + pll_div = 0x19; + ana_pll_div = 0x80; break; } ub960_write(priv, UB960_SR_CSI_PLL_CTL, speed_select, &ret); - 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_ind(priv, UB960_IND_TARGET_CSI_ANA, + UB9702_IR_CSI_ANA_CSIPLL_REG_1, ana_pll_div, &ret); return ret; } From patchwork Fri Jan 10 09:14:12 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tomi Valkeinen X-Patchwork-Id: 13934034 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 3E7E420C484; Fri, 10 Jan 2025 09:15:33 +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=1736500535; cv=none; b=h4stYMrG8USsQR0Y4spyQWycF9FgyEotShvIFwrs1G1nUxWXVnPhWxHXGvaaaY2pi4xOoDN6KmHmVg9ZiXCrDKovu+Bx68s4hjYhJ8LUpYcZb+pOlpdUajBjr4KMjLJu7QAg3xqEn8b58F9HJ00BZwJOIRKsWkK7r3ta4S0szUs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1736500535; c=relaxed/simple; bh=v0ungztLXSbnrvol002IoXFz0dIRmoYaP/UVyF/feSk=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=EhG2r+bmRVQwRXxYYPkYdJeeO8N4c3ohKItpLs1lSdGeOzL+2QK7IkP7U81lM3sHZpb0CRRLP5a0L/cRV4pAdTO603V9X171Vao0p9iooRBuknoTY/r7s/ce/41g5G0HApXF68rlTIolWlq9fY2OTZP/ACcsPFyUS1urgYfXJIM= 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=OhdHO0UO; 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="OhdHO0UO" Received: from [127.0.1.1] (91-158-153-178.elisa-laajakaista.fi [91.158.153.178]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 07D7F1F1A; Fri, 10 Jan 2025 10:14:16 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1736500457; bh=v0ungztLXSbnrvol002IoXFz0dIRmoYaP/UVyF/feSk=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=OhdHO0UOgbB7XTDE5qn+BJXraNjXIrYuuc3duTvBJ8DiPj9nIbASvRI8oKDR6GzGx ZUE+E3Z2WS125s2hGILAqSQ4qGofGWdyhIi+FTPDinjU95fdmW2noeInZC1P4Hgehh YK9JTLYM9kLzG7oxwfAYNp73bYy0fhyJEpvCM97s= From: Tomi Valkeinen Date: Fri, 10 Jan 2025 11:14:12 +0200 Subject: [PATCH 12/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: <20250110-ub9xx-improvements-v1-12-e0b9a1f644da@ideasonboard.com> References: <20250110-ub9xx-improvements-v1-0-e0b9a1f644da@ideasonboard.com> In-Reply-To: <20250110-ub9xx-improvements-v1-0-e0b9a1f644da@ideasonboard.com> To: Mauro Carvalho Chehab Cc: linux-media@vger.kernel.org, linux-kernel@vger.kernel.org, Devarsh Thakkar , Jai Luthra , Sakari Ailus , Tomi Valkeinen X-Mailer: b4 0.13.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=18076; i=tomi.valkeinen@ideasonboard.com; h=from:subject:message-id; bh=v0ungztLXSbnrvol002IoXFz0dIRmoYaP/UVyF/feSk=; b=owEBbQKS/ZANAwAIAfo9qoy8lh71AcsmYgBngOUUQrvWY3BmXO3RMeJ2WnppBP37mnHKbkDkO WctGT+ZY0yJAjMEAAEIAB0WIQTEOAw+ll79gQef86f6PaqMvJYe9QUCZ4DlFAAKCRD6PaqMvJYe 9X//EACaYMBLJ8SRw7QfiNwIIRLx+VYBOtv4/JOilKWqu6tPlS3jrpm73eZPJKHgp6sFUoR46Qc 6S1wtVuLSdm/d0lIpZLzqKSJnIaIzXf2r0I0WuwTiIr4a+6GFXtuP/bXUSopQwl20sb8kra0uNE G3vk7us1n0xAebbc0EJWMZ8wgDK2XfXsJ+JMPS/j0d6vfjqakSm//03U01TBlpymIEtyZOZe89h 5zpcdKQ6Kx1tX9mY+h1Bm3cFcmcvzC8nSqL30zZwwNvx7qz39J3x6emL3wl32hVgz4lwqKbHEnH VTDvVUvUtG5R0HMPWRH/h3ADQk5CIc6LwcwgBTwD1OBbDtOg+Az9o4s0MLizOUZMiw409MiN84l RpDk62z3Mqc2qoJPvbSLK+42uYgqsf/msSgmIStmQifrooq0QDDqmG8G3rDhj/+MLkvASYtwP4Y Wbrri5EljQ53J83lSI+8Z8HMr1FBqDeI0jiG+CefmgDJW9CrcAsgz0wokvnztSspOizLE0ueDRG w0OicRTRBQz+P+Dr3arLFm8H7ilqkLupkc9lz+jz2ZLVUCXesYW7NAbxlp9frWgx3av1OFQADJf 1PRGAaTUEirDwuZYSM50qE8s2HWHea6NAAWR3+TO0T4Z+j6V3oF52HyhGOX9nmeS62SGXorxCT1 7rco9dqaHx8OQCQ== X-Developer-Key: i=tomi.valkeinen@ideasonboard.com; a=openpgp; fpr=C4380C3E965EFD81079FF3A7FA3DAA8CBC961EF5 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 --- 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 bca858172942..02e22ae813fa 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) \ + 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) \ + 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) \ + 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) { + 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) { + 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) { + 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) { + 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) + 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) { 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) { 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) { + 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) { + 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) { + 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) { + 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) { + 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) { + 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) { 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) { + 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) { 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) + 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) + ub960_write(priv, UB960_SR_I2C_RX_ID(it.nport), + (UB960_DEBUG_I2C_RX_ID + it.nport) << 1, NULL); #endif return 0; From patchwork Fri Jan 10 09:14:13 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tomi Valkeinen X-Patchwork-Id: 13934035 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 E99A720CCCC; Fri, 10 Jan 2025 09:15:34 +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=1736500536; cv=none; b=lRpI/g5yUQ168JVbzU7x3X8g1pZrXg4YoxzKbUO7g3qYVGWu/ZJtErY9y8MY46DiSuyqtsOi+jMuM5Qw6DnggriLVlzMMHxc9K7AABYiAs4TxPs1K7YRFEvxPhCdCqU7M2fNDDAxLHpBMc+sgdMkbibxPtw+/ihcgTfTaghDF90= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1736500536; c=relaxed/simple; bh=XjaM0YwOS6nxizbXX1Yzxtppb/eYrdAYkmjsnuSndAo=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=ZcIImrzwVgKjEZG0hhfSWRwXBlS4MpXeNQb7OaqibH+y13BR8G3W7PZanT5pIYVB0brJPL8ZBpgvjDcniUWmuTEJqCsGr6JlV4DSpQzIkGvtuv8lRP62HrSF3Jy21096soQlWMtGKmXIhzRdt0SzAwGDDwSoorlJQW68OVpVnD4= 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=h0oXoeSi; 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="h0oXoeSi" Received: from [127.0.1.1] (91-158-153-178.elisa-laajakaista.fi [91.158.153.178]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 8C2FA269B; Fri, 10 Jan 2025 10:14:17 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1736500457; bh=XjaM0YwOS6nxizbXX1Yzxtppb/eYrdAYkmjsnuSndAo=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=h0oXoeSiYj/Y8JAj3TGO/1JguUnX6BpzOnYkfV00n8acD+UuuK/CI6a2n9i4j/zal XOT8CNfj0zDSw0mZmrYGUIw0cN4ZVVrf46hxavssXiefNpy8e0jkpKi53WDAVjKRsu KrkyDgrCQZc/vUqgw74FJVB2Ru0vmb1ufes39/jQ= From: Tomi Valkeinen Date: Fri, 10 Jan 2025 11:14:13 +0200 Subject: [PATCH 13/19] media: i2c: ds90ub960: Move all RX port init code into ub960_init_rx_ports() Precedence: bulk X-Mailing-List: linux-media@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20250110-ub9xx-improvements-v1-13-e0b9a1f644da@ideasonboard.com> References: <20250110-ub9xx-improvements-v1-0-e0b9a1f644da@ideasonboard.com> In-Reply-To: <20250110-ub9xx-improvements-v1-0-e0b9a1f644da@ideasonboard.com> To: Mauro Carvalho Chehab Cc: linux-media@vger.kernel.org, linux-kernel@vger.kernel.org, Devarsh Thakkar , Jai Luthra , Sakari Ailus , Tomi Valkeinen X-Mailer: b4 0.13.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=4398; i=tomi.valkeinen@ideasonboard.com; h=from:subject:message-id; bh=XjaM0YwOS6nxizbXX1Yzxtppb/eYrdAYkmjsnuSndAo=; b=owEBbQKS/ZANAwAIAfo9qoy8lh71AcsmYgBngOUVvB4cecieAxVScOpf9RKs1jOjhb83x56dU bLQxUiT1FiJAjMEAAEIAB0WIQTEOAw+ll79gQef86f6PaqMvJYe9QUCZ4DlFQAKCRD6PaqMvJYe 9ZJAD/9YCGNXONe5E2ZetHQkPRZEx2mz3oORr7E1Yk4SIROF7+lMSJ6HR9F1aD1ljGIGYGJudN3 gMDXgeOtkajH4DzEtsF80qbXfom0HUdxwxNN6GdhOQ1xgWi0QFJO4PDsCZrhXfp7LC/CEYlXx1c 0vgTYF9W44eSp6oEfQ8IY7UtLkNRqPCLekgaHVS7C1y+Huwfi5k9RYUEoDOsOubv2lGgsHPriIG jZu+B1lk840Hyn2STiNm+x1sqomWKKGvFI5z+U5+Kr95mP+QAVTvBr6KqeEGZHAA+1SyqBSvMHL eVUtfP5+QSakyMtuoWw36/gxPgOG7VN/dF31RH5Gc56ISZnq3TVsl7OXu5W8iovjg6CA+GFgdIr Nhg1Csi3jRLJ9pXHcrJ9llTG5nZr1hA4VvVfMhoLw3Ip8sUK5t8lvQmfANz3TTy+VC+rLOYEvzF j44M1oP4pvfcslJbtC219e2305sPSg1DQTXfb/ZcN/D2rlyy7dPs8u9HruT7wsPaBJu2OCyvK9O 2tDdq8U9+VyzVjYzyfDySRZDNzeK7S5v203JcuC26ixUvpaq4h14BS7hi9lS1HzGZt9yMusAuE7 tcygSrMzl2gopTvgk/5Xs53UOIstxU8TV/xW+owDOXk9vecipjOlQuWlRPx/T4TjQzZ8N+emvBr tLPz8jpVEKLOOhg== X-Developer-Key: i=tomi.valkeinen@ideasonboard.com; a=openpgp; fpr=C4380C3E965EFD81079FF3A7FA3DAA8CBC961EF5 We have some code in probe() which is related to RX port initialization, and should be in ub960_init_rx_ports(). Move the code there. We also move ub960_reset() so that it is accessible from ub960_init_rx_ports(). Signed-off-by: Tomi Valkeinen --- drivers/media/i2c/ds90ub960.c | 115 ++++++++++++++++++++++-------------------- 1 file changed, 59 insertions(+), 56 deletions(-) diff --git a/drivers/media/i2c/ds90ub960.c b/drivers/media/i2c/ds90ub960.c index 02e22ae813fa..cc944d737524 100644 --- a/drivers/media/i2c/ds90ub960.c +++ b/drivers/media/i2c/ds90ub960.c @@ -1225,6 +1225,33 @@ static int ub960_ind_update_bits(struct ub960_data *priv, u8 block, u8 reg, return ret; } +static int ub960_reset(struct ub960_data *priv, bool reset_regs) +{ + struct device *dev = &priv->client->dev; + unsigned int v; + int ret; + u8 bit; + + bit = reset_regs ? UB960_SR_RESET_DIGITAL_RESET1 : + UB960_SR_RESET_DIGITAL_RESET0; + + ret = ub960_write(priv, UB960_SR_RESET, bit, NULL); + if (ret) + return ret; + + mutex_lock(&priv->reg_lock); + + ret = regmap_read_poll_timeout(priv->regmap, UB960_SR_RESET, v, + (v & bit) == 0, 2000, 100000); + + mutex_unlock(&priv->reg_lock); + + if (ret) + dev_err(dev, "reset failed: %d\n", ret); + + return ret; +} + /* ----------------------------------------------------------------------------- * I2C-ATR (address translator) */ @@ -2493,6 +2520,11 @@ static int ub960_init_rx_port_ub9702(struct ub960_data *priv, static int ub960_init_rx_ports(struct ub960_data *priv) { + struct device *dev = &priv->client->dev; + unsigned int port_lock_mask; + unsigned int port_mask; + int ret; + for_each_active_rxport(priv) { int ret; @@ -2505,6 +2537,33 @@ static int ub960_init_rx_ports(struct ub960_data *priv) return ret; } + ret = ub960_reset(priv, false); + if (ret) + return ret; + + port_mask = 0; + + for_each_active_rxport(priv) + port_mask |= BIT(it.nport); + + ret = ub960_rxport_wait_locks(priv, port_mask, &port_lock_mask); + if (ret) + return ret; + + if (port_mask != port_lock_mask) { + ret = -EIO; + dev_err_probe(dev, ret, "Failed to lock all RX ports\n"); + return ret; + } + + /* + * Clear any errors caused by switching the RX port settings while + * probing. + */ + ret = ub960_clear_rx_errors(priv); + if (ret) + return ret; + return 0; } @@ -4168,33 +4227,6 @@ static const struct regmap_config ub960_regmap_config = { .disable_locking = true, }; -static int ub960_reset(struct ub960_data *priv, bool reset_regs) -{ - struct device *dev = &priv->client->dev; - unsigned int v; - int ret; - u8 bit; - - bit = reset_regs ? UB960_SR_RESET_DIGITAL_RESET1 : - UB960_SR_RESET_DIGITAL_RESET0; - - ret = ub960_write(priv, UB960_SR_RESET, bit, NULL); - if (ret) - return ret; - - mutex_lock(&priv->reg_lock); - - ret = regmap_read_poll_timeout(priv->regmap, UB960_SR_RESET, v, - (v & bit) == 0, 2000, 100000); - - mutex_unlock(&priv->reg_lock); - - if (ret) - dev_err(dev, "reset failed: %d\n", ret); - - return ret; -} - static int ub960_get_hw_resources(struct ub960_data *priv) { struct device *dev = &priv->client->dev; @@ -4319,8 +4351,6 @@ static int ub960_probe(struct i2c_client *client) { struct device *dev = &client->dev; struct ub960_data *priv; - unsigned int port_lock_mask; - unsigned int port_mask; int ret; priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); @@ -4367,33 +4397,6 @@ static int ub960_probe(struct i2c_client *client) if (ret) goto err_disable_vpocs; - ret = ub960_reset(priv, false); - if (ret) - goto err_disable_vpocs; - - port_mask = 0; - - for_each_active_rxport(priv) - port_mask |= BIT(it.nport); - - ret = ub960_rxport_wait_locks(priv, port_mask, &port_lock_mask); - if (ret) - goto err_disable_vpocs; - - if (port_mask != port_lock_mask) { - ret = -EIO; - dev_err_probe(dev, ret, "Failed to lock all RX ports\n"); - goto err_disable_vpocs; - } - - /* - * Clear any errors caused by switching the RX port settings while - * probing. - */ - ret = ub960_clear_rx_errors(priv); - if (ret) - goto err_disable_vpocs; - ret = ub960_init_atr(priv); if (ret) goto err_disable_vpocs; From patchwork Fri Jan 10 09:14:14 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tomi Valkeinen X-Patchwork-Id: 13934036 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 4CBDA20D4EE; Fri, 10 Jan 2025 09:15: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=1736500539; cv=none; b=rURlTyamd7dZV8eVnmtzriq6s7cO5M1Rb+cy5M7uw0YpsFaG9Vae9xpIT5DlwL9EAuIh06huoffu3szm+N8ab2od/VdR4qoqQU7VLj3eoY5YA19hw2LzSkX2pgW0vRR54ifO0g+uV/y2L52k1iutwv+Dz630u2FcEqFAdUI+H8Y= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1736500539; c=relaxed/simple; bh=DWToMBwr1xndBK5uWEpp0zwmeBf6j+ydEZOw6FvNts0=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=u7xijdPi7RqWxsvf5tHqZfTQUZ1zw/0SfZcK77CB/B4tD+3iJU1OaaJIk6gUHQf/vfLI7qpxPXOvR5W0PfvGUTkCgYhKEaUbHAHfeKCJhYjKOUXOQjHrJP4ODnkTGUCGHy8GvquhI4Ex+GlMdszTFLLgJSZ6e28KruN91hhS39g= 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=l/9/yeuJ; 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="l/9/yeuJ" Received: from [127.0.1.1] (91-158-153-178.elisa-laajakaista.fi [91.158.153.178]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 22AE6CE6; Fri, 10 Jan 2025 10:14:18 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1736500458; bh=DWToMBwr1xndBK5uWEpp0zwmeBf6j+ydEZOw6FvNts0=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=l/9/yeuJgH+kaIxwMvIzEssTudHUI5m9C+63kIr0nNfyLH7+Kenum9pdrs6eJi9Pc z2sAv2hLQka+hQMDaFgQjFFoXS8kNU/ZbRpcEl45tLB/hctfo4bzI3zz/EImg1dZ7l 9F2S6e3XUoepBks3yPkpNrsYWfWGImKKAYSuSG94= From: Tomi Valkeinen Date: Fri, 10 Jan 2025 11:14:14 +0200 Subject: [PATCH 14/19] media: i2c: ds90ub960: Remove old ub9702 RX port init code (SQUASH) Precedence: bulk X-Mailing-List: linux-media@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20250110-ub9xx-improvements-v1-14-e0b9a1f644da@ideasonboard.com> References: <20250110-ub9xx-improvements-v1-0-e0b9a1f644da@ideasonboard.com> In-Reply-To: <20250110-ub9xx-improvements-v1-0-e0b9a1f644da@ideasonboard.com> To: Mauro Carvalho Chehab Cc: linux-media@vger.kernel.org, linux-kernel@vger.kernel.org, Devarsh Thakkar , Jai Luthra , Sakari Ailus , Tomi Valkeinen X-Mailer: b4 0.13.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=8434; i=tomi.valkeinen@ideasonboard.com; h=from:subject:message-id; bh=DWToMBwr1xndBK5uWEpp0zwmeBf6j+ydEZOw6FvNts0=; b=owEBbQKS/ZANAwAIAfo9qoy8lh71AcsmYgBngOUVzyp2xUSU3/mk0orGb4TQsEb6IxtLZ8HlZ Y6iQtb0z+CJAjMEAAEIAB0WIQTEOAw+ll79gQef86f6PaqMvJYe9QUCZ4DlFQAKCRD6PaqMvJYe 9UDOEACw5fJnSjq4pp3NqzuISwNH1Vgd2oMT7axPkoYW6bUxsxLXxLSaXp6o4up3A1iXzz8XJZd eStwq4lfrPh+tLGenwEkINVkBAlu5M6xyLzc0C354N/8hdA5d8Z/3sxoTyJ1IyeTyzcLybQBY3R dUQTpSoaSHy42l1HvrE/S+vByjHutVZN122TvxJgktnre88XrYWrjrF3ttZFgGkp5ySvVSeSoy+ UkcKXpNFt1HfYPT1oRVsgUYEwqdErYHEcK7omRoJ9QIu8TVTdl1W0PCvrUAK6ZDk76ASRgr/KXR hO9oiRbCAchbnjz5M3lAw0oKGZp0xTa430Butqw/aIvCvcXbq4uJ5Qsk5o35I+6dg/NrIVdRXWG vFC491d1DBL/3rgh546hPbcQzRztB5vZNVHjR4YhOCqBDbteKgFgA+k76pWQJr6BXRHSEUuryRu HUxm0JjOmcusMiQ1iRp2ftN0a97VDYfHYmgb0s+lADrluSjTITGs+XgPRstXcsewp/WlveBSolL m8BbhTqwArb8YxUAT23egUNusjo+XNizTftpc0LdEOVavqWol0xBWyrZVflEC9jyc1WY9cUSWsV uG144b7Tvr/Q4DP01Fud4tWVuDve1TMaAEoc70m1wiBynZ82D2ibmmpPt8Tl2tOFbcaCGIZ9IIc EksKlx6xonC0tpA== X-Developer-Key: i=tomi.valkeinen@ideasonboard.com; a=openpgp; fpr=C4380C3E965EFD81079FF3A7FA3DAA8CBC961EF5 We will refresh ub9702 RX port initialization code in the following patch. To make that patch easier to review, remove the old ub9702 code here. This should be squashed in the final version. Signed-off-by: Tomi Valkeinen --- drivers/media/i2c/ds90ub960.c | 273 +----------------------------------------- 1 file changed, 3 insertions(+), 270 deletions(-) diff --git a/drivers/media/i2c/ds90ub960.c b/drivers/media/i2c/ds90ub960.c index cc944d737524..dc9ead85c676 100644 --- a/drivers/media/i2c/ds90ub960.c +++ b/drivers/media/i2c/ds90ub960.c @@ -2257,268 +2257,7 @@ 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) -{ - unsigned int nport = rxport->nport; - u8 bc_freq_val; - u8 fpd_func_mode; - int ret = 0; - - switch (rxport->rx_mode) { - case RXPORT_MODE_RAW10: - bc_freq_val = 0; - fpd_func_mode = 5; - break; - - case RXPORT_MODE_RAW12_HF: - bc_freq_val = 0; - fpd_func_mode = 4; - break; - - case RXPORT_MODE_RAW12_LF: - bc_freq_val = 0; - fpd_func_mode = 6; - break; - - case RXPORT_MODE_CSI2_SYNC: - bc_freq_val = 6; - fpd_func_mode = 2; - break; - - case RXPORT_MODE_CSI2_NONSYNC: - bc_freq_val = 2; - fpd_func_mode = 2; - break; - - default: - return -EINVAL; - } - - 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); - - /* set serdes_eq_mode = 1 */ - ub960_write_ind(priv, UB960_IND_TARGET_RX_ANA(nport), 0xa8, 0x80, - &ret); - - /* enable serdes driver */ - ub960_write_ind(priv, UB960_IND_TARGET_RX_ANA(nport), 0x0d, 0x7f, - &ret); - - /* set serdes_eq_offset=4 */ - ub960_write_ind(priv, UB960_IND_TARGET_RX_ANA(nport), 0x2b, 0x04, - &ret); - - /* init default serdes_eq_max in 0xa9 */ - ub960_write_ind(priv, UB960_IND_TARGET_RX_ANA(nport), 0xa9, 0x23, - &ret); - - /* init serdes_eq_min in 0xaa */ - ub960_write_ind(priv, UB960_IND_TARGET_RX_ANA(nport), 0xaa, 0, &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); - - /* RX port to half-rate */ - ub960_update_bits(priv, UB9702_SR_FPD_RATE_CFG, 0x3 << (nport * 2), - BIT(nport * 2), &ret); - - return ret; -} - -static int ub960_init_rx_port_ub9702_fpd4_aeq(struct ub960_data *priv, - struct ub960_rxport *rxport) -{ - unsigned int nport = rxport->nport; - bool first_time_power_up = true; - 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); - - 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); - - ub960_write_ind(priv, UB960_IND_TARGET_RX_ANA(nport), 0x2b, - 0x00, &ret); - } - - /* enable serdes_eq_ctl2 */ - ub960_write_ind(priv, UB960_IND_TARGET_RX_ANA(nport), 0x9e, 0x00, - &ret); - - /* enable serdes_eq_ctl1 */ - ub960_write_ind(priv, UB960_IND_TARGET_RX_ANA(nport), 0x90, 0x40, - &ret); - - /* enable serdes_eq_en */ - ub960_write_ind(priv, UB960_IND_TARGET_RX_ANA(nport), 0x2e, 0x40, - &ret); - - /* disable serdes_eq_override */ - ub960_write_ind(priv, UB960_IND_TARGET_RX_ANA(nport), 0xf0, 0x00, - &ret); - - /* disable serdes_gain_override */ - ub960_write_ind(priv, UB960_IND_TARGET_RX_ANA(nport), 0x71, 0x00, - &ret); - - return ret; -} - -static int ub960_init_rx_port_ub9702_fpd4(struct ub960_data *priv, - struct ub960_rxport *rxport) -{ - 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; - - case RXPORT_MODE_RAW12_HF: - bc_freq_val = 0; - break; - - case RXPORT_MODE_RAW12_LF: - bc_freq_val = 0; - break; - - case RXPORT_MODE_CSI2_SYNC: - bc_freq_val = 6; - break; - - case RXPORT_MODE_CSI2_NONSYNC: - bc_freq_val = 2; - break; - - default: - return -EINVAL; - } - - ub960_rxport_update_bits(priv, nport, UB960_RR_BCC_CONFIG, 0x7, - bc_freq_val, &ret); - - /* FPD4 Sync Mode */ - 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, - &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); - - /* 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); - - /* 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); - - /* RX port to 7.55G mode */ - ub960_update_bits(priv, UB9702_SR_FPD_RATE_CFG, 0x3 << (nport * 2), - 0 << (nport * 2), &ret); - - if (ret) - return ret; - - ret = ub960_init_rx_port_ub9702_fpd4_aeq(priv, rxport); - if (ret) - return ret; - - return 0; -} - -static int ub960_init_rx_port_ub9702(struct ub960_data *priv, - struct ub960_rxport *rxport) -{ - unsigned int nport = rxport->nport; - int ret; - - 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); - - 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); - - break; - - case RXPORT_MODE_RAW12_HF: - case RXPORT_MODE_RAW12_LF: - /* Not implemented */ - return -EINVAL; - - case RXPORT_MODE_CSI2_SYNC: - case RXPORT_MODE_CSI2_NONSYNC: - - break; - } - - /* LV_POLARITY & FV_POLARITY */ - ub960_rxport_update_bits(priv, nport, UB960_RR_PORT_CONFIG2, 0x3, - rxport->lv_fv_pol, &ret); - - /* 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); - - /* 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); - - /* 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); - - /* Enable RX port */ - ub960_update_bits(priv, UB960_SR_RX_PORT_CTL, BIT(nport), BIT(nport), - &ret); - - if (rxport->cdr_mode == RXPORT_CDR_FPD4) { - /* unreset 960 AEQ */ - ub960_write_ind(priv, UB960_IND_TARGET_RX_ANA(nport), 0x25, - 0x41, &ret); - } - - return ret; -} - -static int ub960_init_rx_ports(struct ub960_data *priv) +static int ub960_init_rx_ports_ub960(struct ub960_data *priv) { struct device *dev = &priv->client->dev; unsigned int port_lock_mask; @@ -2526,13 +2265,7 @@ static int ub960_init_rx_ports(struct ub960_data *priv) int ret; for_each_active_rxport(priv) { - int 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); - + ret = ub960_init_rx_port_ub960(priv, it.rxport); if (ret) return ret; } @@ -4393,7 +4126,7 @@ static int ub960_probe(struct i2c_client *client) if (ret) goto err_free_ports; - ret = ub960_init_rx_ports(priv); + ret = ub960_init_rx_ports_ub960(priv); if (ret) goto err_disable_vpocs; From patchwork Fri Jan 10 09:14:15 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tomi Valkeinen X-Patchwork-Id: 13934037 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 491E720CCED; Fri, 10 Jan 2025 09:15: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=1736500540; cv=none; b=YkAUJ7QsgM3DisrzC4xVvP4NogXh0YMLkdWd/kE0vv9doNIK3NBoFpNsSwoTSMOv5LTfHKW2yy65zTpTHf5BNOWQk5gaDPGn25lnQGFkS2ue4HHR4Uaooal2v76ppdmt0uqQR8SgSiOpKzqFrbh6rdjwnN7Vdt4JDa8Ilw8Ntlg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1736500540; c=relaxed/simple; bh=vfOxA8wC5QPaXEVbmSBPXb28x+kwIoZ7rDdOUd3HVb4=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=eHTjtcFGxgRYUrrCqAgyA1kiiuig1Jo98+kmXHdTE9MWX2oplDgy985nKCxnJ4TW/XNBMPN6gm/+bFJt9dWpyZvngZ3qlXnPy6E0JmIRkFd3VfbwdLc+QF7J4XbScp3D2FkFAXFnYtzuAfdpw4Aqb658IQr+OSqCaMwtbsdU9X8= 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=Su2lJUok; 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="Su2lJUok" Received: from [127.0.1.1] (91-158-153-178.elisa-laajakaista.fi [91.158.153.178]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id A8FF8269C; Fri, 10 Jan 2025 10:14:18 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1736500459; bh=vfOxA8wC5QPaXEVbmSBPXb28x+kwIoZ7rDdOUd3HVb4=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=Su2lJUokKjrwXzGu+jUUydQcLsRSR7c6o28qx2UOg7ykDR49xh/QCcYirP6FnecBT 4x4v+OfwAZk7ngxh+51R9mIqdUqLzRQoJi10NIZfOhn0JWFrqoc9kSslVj5sk19KaM jNH7/zkhV22o+RN6yv+spLBLd9HHhN23JDDKUqQ4= From: Tomi Valkeinen Date: Fri, 10 Jan 2025 11:14:15 +0200 Subject: [PATCH 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: <20250110-ub9xx-improvements-v1-15-e0b9a1f644da@ideasonboard.com> References: <20250110-ub9xx-improvements-v1-0-e0b9a1f644da@ideasonboard.com> In-Reply-To: <20250110-ub9xx-improvements-v1-0-e0b9a1f644da@ideasonboard.com> To: Mauro Carvalho Chehab Cc: linux-media@vger.kernel.org, linux-kernel@vger.kernel.org, Devarsh Thakkar , Jai Luthra , Sakari Ailus , Tomi Valkeinen X-Mailer: b4 0.13.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=21719; i=tomi.valkeinen@ideasonboard.com; h=from:subject:message-id; bh=vfOxA8wC5QPaXEVbmSBPXb28x+kwIoZ7rDdOUd3HVb4=; b=owEBbQKS/ZANAwAIAfo9qoy8lh71AcsmYgBngOUVTPSxD1YzfgnUfqUEeY3FeEmAPHEB61AUH 7ywMNFBk0iJAjMEAAEIAB0WIQTEOAw+ll79gQef86f6PaqMvJYe9QUCZ4DlFQAKCRD6PaqMvJYe 9RLqD/9FdpQhATP3EcIksEGlLmVTa8rp6YMK3LJU+nfG9q9GwYucEBIuCf7cPrtW+20rMZdi4wk 5hqyoep73hmBo/ox5DewrArc9LNp6IbRYbDoa7WgL+3jx5RyRwXm5p5azAeQd8ikkIbP8KTqLpx Bcl/pz6nZ4IBIpcSB5N35nQIT66Ej2OJ/zxFUgIh/UgUNP4pVDu/gLBuV0jhHv2vCevLRT5m51t EJKlAnzIJdz0LWiWfN7b3e7RLWZOhubjhVPvLTn8eezVShivNpthi+KFMdq8ysO9Y7N227HUNrn 52+GIliiM8v82DRFA4pIayCPfI+QxBmco//vZwT+JwBNLJUbGuPUXKHaFGAHUSTQTXLAM7HNqhQ RJr/UMMhqJ3Bls1U2dzkkUc3oDmucqN+DRRvAieYL1iztM6Vu2tVvhgApyZYxIZOzZDM1Irr6Ck EgjgL41TW86cmpysmJ1pHW+fY/auv9FQ22TVF8Im89NKiVuvF1lPK8AyxwbSb8SXmvQ9uvO73H6 Kk1Daa9pOwwVuNghR0GiVoMwVs9FULxD0mQCToplGwRzhd06bc746vJQJn65vpISIDtq3ALs/4B ItXwSrqwkwxehAhYCHuWmfZtN56KJtwavLCjiXsmU9dVZPPekz6W/vvubBu1No+nny2IE+VZUI/ JGw8ZVtkYLZbT4Q== X-Developer-Key: i=tomi.valkeinen@ideasonboard.com; a=openpgp; fpr=C4380C3E965EFD81079FF3A7FA3DAA8CBC961EF5 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 --- drivers/media/i2c/ds90ub960.c | 737 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 736 insertions(+), 1 deletion(-) diff --git a/drivers/media/i2c/ds90ub960.c b/drivers/media/i2c/ds90ub960.c index dc9ead85c676..f6d6c2fe12cd 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 @@ -2300,6 +2328,709 @@ static int ub960_init_rx_ports_ub960(struct ub960_data *priv) return 0; } +/* + * UB9702 specific initial RX port configuration + */ + +static int ub960_turn_off_rxport_ub9702(struct ub960_data *priv, + unsigned int nport) +{ + int ret = 0; + + /* 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); + + /* PI disabled and oDAC disabled */ + ub960_write_ind(priv, UB960_IND_TARGET_RX_ANA(nport), + UB9702_IR_RX_ANA_AEQ_CFG_4, 0x09, &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); + + /* 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_set_bc_drv_config_ub9702(struct ub960_data *priv, + unsigned int nport) +{ + u8 fpd_bc_ctl0; + u8 fpd_bc_ctl1; + u8 fpd_bc_ctl2; + int ret = 0; + + if (priv->rxports[nport]->cdr_mode == RXPORT_CDR_FPD4) { + /* Set FPD PBC drv into FPD IV mode */ + + fpd_bc_ctl0 = 0; + fpd_bc_ctl1 = 0; + fpd_bc_ctl2 = 0; + } else { + /* Set FPD PBC drv into FPD III mode */ + + fpd_bc_ctl0 = 2; + fpd_bc_ctl1 = 1; + fpd_bc_ctl2 = 5; + } + + 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); + + 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); + + 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); + + return 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_set_fpd4_async_mode_ub9702(struct ub960_data *priv, + unsigned int nport) +{ + int ret = 0; + + /* FPD4 ASync Mode */ + ub960_rxport_write(priv, nport, UB9702_RR_CHANNEL_MODE, 0x1, &ret); + + /* 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); + + 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 Recover */ + 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_set_fpd3_sync_mode_ub9702(struct ub960_data *priv, + unsigned int nport) +{ + int ret = 0; + + /* FPD3 Sync Mode */ + ub960_rxport_write(priv, nport, UB9702_RR_CHANNEL_MODE, 0x2, &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); + + /* 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_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_set_raw10_dvp_mode_ub9702(struct ub960_data *priv, + unsigned int nport) +{ + int ret = 0; + + /* 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; + + 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_CDR_FPD3: + switch (rxport->rx_mode) { + case RXPORT_MODE_CSI2_SYNC: + ret = ub960_set_fpd3_sync_mode_ub9702(priv, nport); + if (ret) + return ret; + + 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; + } + + return 0; +} + +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; + + ret = ub960_rxport_read(priv, nport, UB960_RR_RX_PORT_STS1, + &port_sts1, NULL); + if (ret) + return ret; + + rx_lock = port_sts1 & UB960_RR_RX_PORT_STS1_PORT_PASS; + + 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; + + 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; + } + } + + dev_err(dev, "rx%u: max number of retries: %s\n", nport, + rx_lock ? "unstable AEQ" : "no lock"); + + return -EIO; +} + +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 = 0; + bool have_fpd4 = false; + int ret; + + for_each_active_rxport(priv) { + 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; + } + + /* 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) { + /* 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) { + port_mask |= BIT(it.nport); + + if (it.rxport->cdr_mode == RXPORT_CDR_FPD4) + have_fpd4 = true; + } + + for_each_rxport(priv) { + ret = ub960_configure_rx_port_ub9702(priv, it.nport); + if (ret) + return ret; + } + + ret = ub960_reset(priv, false); + if (ret) + return ret; + + if (have_fpd4) { + for_each_active_rxport_fpd4(priv) { + /* Release state machine */ + ret = ub960_rxport_write(priv, it.nport, + UB9702_RR_RX_SM_SEL_2, 0x0, + NULL); + if (ret) + return ret; + + dev_dbg(dev, "rx%u: state machine released\n", + it.nport); + } + + /* Wait for SM to resume */ + fsleep(5000); + + for_each_active_rxport_fpd4(priv) { + 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) { + ret = ub960_lock_recovery_ub9702(priv, it.nport); + if (ret) + return ret; + } + + for_each_active_rxport_fpd4(priv) { + ret = ub960_enable_aeq_lms_ub9702(priv, it.nport); + if (ret) + return ret; + } + + for_each_active_rxport_fpd4(priv) { + /* 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) { + /* 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) { + 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) + return ret; + + if (port_mask != port_lock_mask) { + ret = -EIO; + dev_err_probe(dev, ret, "Failed to lock all RX ports\n"); + return ret; + } + + for_each_active_rxport(priv) { + /* 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) { + 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; + + return 0; +} + static int ub960_rxport_handle_events(struct ub960_data *priv, u8 nport) { struct device *dev = &priv->client->dev; @@ -4126,7 +4857,11 @@ static int ub960_probe(struct i2c_client *client) if (ret) goto err_free_ports; - ret = ub960_init_rx_ports_ub960(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 Fri Jan 10 09:14:16 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tomi Valkeinen X-Patchwork-Id: 13934038 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 1200720DD60; Fri, 10 Jan 2025 09:15:40 +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=1736500542; cv=none; b=pSu/Gs6ATavM0ZhEEKMWWnzRRFQEE/QsrKRkotTVh+xIlTivHJtqHOEOwVc0YppJuPja/szYH7lx8hfKq+5WFzuG7ATIMVcCYDq9KTgMceBhpb/L8rT/mjtfVpxozYCqiE2YqjLLFz2c6+a8OuD6a7ZFjcREe9YvjIW/2qs5sR8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1736500542; c=relaxed/simple; bh=BgxP5q3nFf0C/jvErBc553TL/VBiEqjyGqdvT8yt7rM=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=UFKMLJvQywdGeapUyTEuDZ3ygM/r6a2whO317HOXH5qYDaduaI0A6hXb8FbSaCtk616aZaP4O8CcicIOQ3KDAleVtIbGq/MeKyCxLGMPgZk+dkNeRpg6wPVPXmogSz1GsjuQq7CiIpwrvROc2ewtTqVSJDN4xacN+PaSZQKu1OQ= 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=OZ0bcZ4k; 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="OZ0bcZ4k" Received: from [127.0.1.1] (91-158-153-178.elisa-laajakaista.fi [91.158.153.178]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 3E06C8FA; Fri, 10 Jan 2025 10:14:19 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1736500459; bh=BgxP5q3nFf0C/jvErBc553TL/VBiEqjyGqdvT8yt7rM=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=OZ0bcZ4k/fKDBTVp3Na63SVsC0Iby6CAVE6kdYeXcp2nO4LAoLOmtazjyOCMDxr84 no3x3AQrj6c5JmHkwfNYTdndF/Aaj6LOfByku2cu3WoqfV2p9Ip/vTXCoQZZBmIxcc Xz9gjAQRqFBdm6FqV+z3Hh47bHdqgBn0ggzYQeeI= From: Tomi Valkeinen Date: Fri, 10 Jan 2025 11:14:16 +0200 Subject: [PATCH 16/19] media: i2c: ds90ub960: Enable SSCG for UB9702 Precedence: bulk X-Mailing-List: linux-media@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20250110-ub9xx-improvements-v1-16-e0b9a1f644da@ideasonboard.com> References: <20250110-ub9xx-improvements-v1-0-e0b9a1f644da@ideasonboard.com> In-Reply-To: <20250110-ub9xx-improvements-v1-0-e0b9a1f644da@ideasonboard.com> To: Mauro Carvalho Chehab Cc: linux-media@vger.kernel.org, linux-kernel@vger.kernel.org, Devarsh Thakkar , Jai Luthra , Sakari Ailus , Tomi Valkeinen X-Mailer: b4 0.13.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=5570; i=tomi.valkeinen@ideasonboard.com; h=from:subject:message-id; bh=BESZ/HsALuJYRTDP8fgQp5zYdub3KJloOdj8y9w91JI=; b=owEBbQKS/ZANAwAIAfo9qoy8lh71AcsmYgBngOUW4Jfbm5HN0lBCL1mwKqWpqCn2CzcQr4Txj nVBrPxLwwaJAjMEAAEIAB0WIQTEOAw+ll79gQef86f6PaqMvJYe9QUCZ4DlFgAKCRD6PaqMvJYe 9YDeD/9yPMFspV5PFvUBHMwfMEJmQTTh1SUbaq9SuEuyOOuKm6pUGHYLANP0G1EswqK1f2eTvKo TWhBaOM93J10RWvftbFkrA5WtcMH01CmDP+aQnJTiF4/ZpfLDSa95RcZoV8UGVS1sNYtaf2VKgN SqKsVCj2xDbdvdrBveVYBuxNUU12ItuXMqukINp1pfUl35jnI1aegTrIRmDq06i9k+Rj0iWmiLO yDZDQezjcuTJE8t5KFZopoPcsMCCM4BPUiViFJME6g9aDelFCYhAS78VppHOOhgDLdVEM35neSQ 8tkl9aaOTYzkzx0NphWwO9WMs6Mkr7WJTFo69vfUr0jVhrX4kpn1oJOK0q1bS/HD025zJ7NG8CH uYmskCxS8PIwh/WK8luzRreW8gCjfYvVakqCoWT1y2yAz2QMoD3cNknQVvKB+nPqjYSLF0vNWg5 EQx5VNzAtcfxGxy4xxEDdT7tvnXvqW4y2eJm0xvNEQ/CZXoCo2DHuqm6ZWaXDLH5yKDvUVDXMYn tIuDP38HX9GZyC8nHBGyTZcuCMxktwwTv6bGRpBmUq3v0aJSkE4fTxnaqP81nLHKvpnDm8tJlOu 3/nWeK1A2gMQO43GdtWP+ywNGLtvX+l1mEc7D3D5/GoaxCpofDQ9G7zzMvZwlNhG7lo3qCCoohO vzrtRFjf+XuxeWw== X-Developer-Key: i=tomi.valkeinen@ideasonboard.com; a=openpgp; fpr=C4380C3E965EFD81079FF3A7FA3DAA8CBC961EF5 From: Jai Luthra UB9702 supports spread-spectrum clock generation for the back-channel clock, which is futher used by serializers in synchronous mode to generate the forward-channel clock, which can help reduce peak EMI energy. The SSCG is common to all RX ports, so it can only be used if all the ports are in the same mode. Add basic support for SSCG by adding a module parameter to enable the SSCG. The SSCG uses hardcoded configurationg, with 0.5% center-spread at 33kHz modulation rate. See datasheet if different configuration is required. Signed-off-by: Jai Luthra Signed-off-by: Tomi Valkeinen --- drivers/media/i2c/ds90ub960.c | 102 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 102 insertions(+) diff --git a/drivers/media/i2c/ds90ub960.c b/drivers/media/i2c/ds90ub960.c index f6d6c2fe12cd..a534d077f045 100644 --- a/drivers/media/i2c/ds90ub960.c +++ b/drivers/media/i2c/ds90ub960.c @@ -52,6 +52,10 @@ #include #include +static bool ub960_enable_sscg; +module_param_named(enable_sscg, ub960_enable_sscg, bool, 0644); +MODULE_PARM_DESC(enable_sscg, "Enable SSCG (if available)"); + #define MHZ(v) ((u32)((v) * HZ_PER_MHZ)) /* @@ -359,6 +363,7 @@ /* Indirect register blocks */ #define UB960_IND_TARGET_PAT_GEN 0x00 #define UB960_IND_TARGET_RX_ANA(n) (0x01 + (n)) +#define UB960_IND_TARGET_PLL_CTRL 0x05 #define UB960_IND_TARGET_CSI_ANA 0x07 /* UB960_IR_PGEN_*: Indirect Registers for Test Pattern Generator */ @@ -382,6 +387,22 @@ #define UB960_IR_PGEN_VFP 0x0f #define UB960_IR_PGEN_COLOR(n) (0x10 + (n)) /* n < 15 */ +#define UB960_IR_PLL_DEN_MASH2 0x80 +#define UB960_IR_PLL_DEN_MASH1 0x81 +#define UB960_IR_PLL_DEN_MASH0 0x82 +#define UB960_IR_PLL_NUM_MASH2 0x83 +#define UB960_IR_PLL_NUM_MASH1 0x84 +#define UB960_IR_PLL_NUM_MASH0 0x85 +#define UB960_IR_PLL_NCOUNT1 0x86 +#define UB960_IR_PLL_NCOUNT0 0x87 +#define UB960_IR_PLL_SSCG_CTRL1 0x88 +#define UB960_IR_PLL_MASH_ORDER 0x8a +#define UB960_IR_PLL_SSCG_CTRL2 0x8b +#define UB960_IR_PLL_SSCG_CTRL3 0x8c +#define UB960_IR_PLL_SSCG_CTRL4 0x8d +#define UB960_IR_PLL_SSCG_CTRL5 0x8e +#define UB960_IR_PLL_SSCG_MASH_CTRL 0x8f + #define UB960_IR_RX_ANA_STROBE_SET_CLK 0x08 #define UB960_IR_RX_ANA_STROBE_SET_CLK_NO_EXTRA_DELAY BIT(3) #define UB960_IR_RX_ANA_STROBE_SET_CLK_DELAY_MASK GENMASK(2, 0) @@ -2837,6 +2858,81 @@ static int ub960_enable_dfe_lms_ub9702(struct ub960_data *priv, return 0; } +/* + * Configures back-channel spread-spectrum clocking with 0.5% center-spread at + * 33kHz modulation rate. See datasheet if different configuration is required. + */ +static int ub960_enable_sscg_ub9702(struct ub960_data *priv) +{ + struct device *dev = &priv->client->dev; + int ret = 0; + + /* + * The configuration is hard-coded with FPD4 and BC frequency + * 47.1875Mbps, so make sure all RX ports are configured with + * synchronous clocking mode. + */ + for_each_active_rxport(priv) { + if (it.rxport->cdr_mode != RXPORT_CDR_FPD4 || + it.rxport->rx_mode != RXPORT_MODE_CSI2_SYNC) { + dev_warn(dev, + "rx%u: Not in FPD4 SYNC mode, skipping SSCG\n", + it.nport); + return 0; + } + } + + /* Disable MASH */ + ub960_write_ind(priv, UB960_IND_TARGET_PLL_CTRL, + UB960_IR_PLL_SSCG_MASH_CTRL, 0x40, &ret); + + /* Set MASH denominator */ + ub960_write_ind(priv, UB960_IND_TARGET_PLL_CTRL, UB960_IR_PLL_DEN_MASH2, + 0x7f, &ret); + ub960_write_ind(priv, UB960_IND_TARGET_PLL_CTRL, UB960_IR_PLL_DEN_MASH1, + 0xff, &ret); + ub960_write_ind(priv, UB960_IND_TARGET_PLL_CTRL, UB960_IR_PLL_DEN_MASH0, + 0xf8, &ret); + + /* Set MASH numerator */ + ub960_write_ind(priv, UB960_IND_TARGET_PLL_CTRL, UB960_IR_PLL_NUM_MASH2, + 0x7f, &ret); + ub960_write_ind(priv, UB960_IND_TARGET_PLL_CTRL, UB960_IR_PLL_NUM_MASH1, + 0xff, &ret); + ub960_write_ind(priv, UB960_IND_TARGET_PLL_CTRL, UB960_IR_PLL_NUM_MASH0, + 0xf8, &ret); + + /* Set NCOUNT */ + ub960_write_ind(priv, UB960_IND_TARGET_PLL_CTRL, UB960_IR_PLL_NCOUNT1, + 0x00, &ret); + ub960_write_ind(priv, UB960_IND_TARGET_PLL_CTRL, UB960_IR_PLL_NCOUNT0, + 0x96, &ret); + + /* Set MASH order */ + ub960_write_ind(priv, UB960_IND_TARGET_PLL_CTRL, + UB960_IR_PLL_MASH_ORDER, 0x20, &ret); + + /* Set rampx increment and stop */ + ub960_write_ind(priv, UB960_IND_TARGET_PLL_CTRL, + UB960_IR_PLL_SSCG_CTRL2, 0xbd, &ret); + ub960_write_ind(priv, UB960_IND_TARGET_PLL_CTRL, + UB960_IR_PLL_SSCG_CTRL4, 0x73, &ret); + ub960_write_ind(priv, UB960_IND_TARGET_PLL_CTRL, + UB960_IR_PLL_SSCG_CTRL5, 0x41, &ret); + + /* Enable SSCG */ + ub960_ind_update_bits(priv, UB960_IND_TARGET_PLL_CTRL, + UB960_IR_PLL_SSCG_CTRL1, BIT(7), BIT(7), &ret); + + /* Enable MASH */ + ub960_write_ind(priv, UB960_IND_TARGET_PLL_CTRL, + UB960_IR_PLL_SSCG_MASH_CTRL, 0x0, &ret); + + dev_dbg(dev, "SSCG enabled\n"); + + return ret; +} + static int ub960_init_rx_ports_ub9702(struct ub960_data *priv) { struct device *dev = &priv->client->dev; @@ -2860,6 +2956,12 @@ static int ub960_init_rx_ports_ub9702(struct ub960_data *priv) if (ret) return ret; + if (ub960_enable_sscg) { + ret = ub960_enable_sscg_ub9702(priv); + if (ret) + return ret; + } + for_each_active_rxport_fpd4(priv) { /* Hold state machine in reset */ ub960_rxport_write(priv, it.nport, UB9702_RR_RX_SM_SEL_2, 0x10, From patchwork Fri Jan 10 09:14:17 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tomi Valkeinen X-Patchwork-Id: 13934039 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 6E6BF20DD75; Fri, 10 Jan 2025 09:15:42 +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=1736500544; cv=none; b=UC4jaD4LiGrL173XxHxFJxMB5KPmoDsiEzFvUmvRHUdxp8BpHcj83/whpyKjUDeu/HZTsP1lhlDJqTfN5aBHYNGu4nyX86Ucu0omArK3DI3BNjJBqohUz9VP8SZ2B2W/iBCWPJyYOaTEe2Tq19tV0BYAQ3iYT0k/SaYTX0iVGs4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1736500544; c=relaxed/simple; bh=sfFux45FQcncQHHLAZmUrqaIyq2629TmZ7HxcgGYM7w=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=r+D3YMTfPJOOe2xTC56/XXU92Q39eG/wbFlA6atiQBeznsbidMdfCH2oP8HKFKu49auxW5qfkSy35f2tA9wdIcocVmCYfDl6icZUPbtLGpjE2xQGGqtQIIBHJ7aEK9VFWIk0iu8N2Gajn6Fd3o+bbtQHUJJPhiCYzewkxaL6sBM= 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=dZZ4iX4S; 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="dZZ4iX4S" Received: from [127.0.1.1] (91-158-153-178.elisa-laajakaista.fi [91.158.153.178]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id C436826A1; Fri, 10 Jan 2025 10:14:19 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1736500460; bh=sfFux45FQcncQHHLAZmUrqaIyq2629TmZ7HxcgGYM7w=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=dZZ4iX4SgIAGpqwP4alh7JbO1yBkdjg6BguA1GxTbVkjtqAAOaF7Yxhu+ggVnHxAe i88N+j8kdfASGwiCYT2jmVNM+i7R2uXTT7bH4Pawnukiq6/IGVaxKVqfJjjk30U1RT FW1U4ZZ28n2bnjBcTYfAig4smZoffdyfzTn+e0dU= From: Tomi Valkeinen Date: Fri, 10 Jan 2025 11:14:17 +0200 Subject: [PATCH 17/19] media: dt-bindings: ti,ds90ub960: Add "i2c-addr" link property Precedence: bulk X-Mailing-List: linux-media@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20250110-ub9xx-improvements-v1-17-e0b9a1f644da@ideasonboard.com> References: <20250110-ub9xx-improvements-v1-0-e0b9a1f644da@ideasonboard.com> In-Reply-To: <20250110-ub9xx-improvements-v1-0-e0b9a1f644da@ideasonboard.com> To: Mauro Carvalho Chehab Cc: linux-media@vger.kernel.org, linux-kernel@vger.kernel.org, Devarsh Thakkar , Jai Luthra , Sakari Ailus , Tomi Valkeinen , devicetree@vger.kernel.org, Rob Herring , Krzysztof Kozlowski X-Mailer: b4 0.13.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=1719; i=tomi.valkeinen@ideasonboard.com; h=from:subject:message-id; bh=GDTLyS9Si8q6ga2oVEsfw2W8NhUNtYkaUlhU96iZCzU=; b=owEBbQKS/ZANAwAIAfo9qoy8lh71AcsmYgBngOUWSSZWGpf7vTZOk6zfV9ekwY9MhJJDj5mVf MZZOOxeiRGJAjMEAAEIAB0WIQTEOAw+ll79gQef86f6PaqMvJYe9QUCZ4DlFgAKCRD6PaqMvJYe 9RXuD/9JS6B4RAQuwpqCx9hxlbIEXzXAAWC3A+GYRkKAVOZ5kDyQ6KHbT0YC3JxmX8UAOOMw36Y YEGwEaGUS9sfqqtG2SJFrdzmRXXv0LeYhXXcC9IivqpzeacInf01KKsz5ERP6+2eKCHZmUP2j2o 5aQGCoOG5EaTF6eZjwBzbeQYskLq6UBPgR1gwRgh/Y2f0VGfNzHvFIyiJSI7Z/EABzftDwMUpzF Ddt+cxdoVTM5VqBOPl1pPdwPQNwkMsFCXN1fJA+sWOA51DgzyXQCpDGZ4AFW+RazI1Y1neGXGww bFjpo7HbvMN1Gvqa2/NuTIpijkeKEeFE5irTkKBu/v8JIz730ukqgjPxySzAhv06DVm90ZRYtF5 h8z0AmF9Jf0ktFstB3sl1o6TYE1JUixkybTLNk957z0Ro0jpcAskqZvIbJQHPf2eQnUc1R3tIOD drWAWkczf3pjxp8WWtfsoi8kLEmzBsaXENv349FJKXmOEInI7a03Xhrx//Jne7fCCEzQ/uJhSiX KzXbJcV+90kLZwI8e57uxce5i0ei0QuieG9qaCQyKojGRpdMnmPVJcutA5EmcrprYwb2EHNoc+r HzPjNNVIoMDxrWm5Zxs9KKwzkVzTUER6Feuscmw4B4ns6qsZ8U4OB6gTGfo350PiHU1vicfPrDF 6ylzY1f96s85uuw== X-Developer-Key: i=tomi.valkeinen@ideasonboard.com; a=openpgp; fpr=C4380C3E965EFD81079FF3A7FA3DAA8CBC961EF5 From: Jai Luthra The serializer's I2C address on the FPD-Link bus is usually communicated to the deserializer once the forward-channel is established. But in some cases it might be necessary to program the serializer (over the back-channel) before the forward-channel is established. This can be used e.g. to correct serializer configuration which otherwise would prevent the FC to be enabled. Add a new optional property to specify the I2C address of the serializer. Signed-off-by: Jai Luthra Signed-off-by: Tomi Valkeinen Cc: devicetree@vger.kernel.org Cc: Rob Herring Cc: Krzysztof Kozlowski --- Documentation/devicetree/bindings/media/i2c/ti,ds90ub960.yaml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Documentation/devicetree/bindings/media/i2c/ti,ds90ub960.yaml b/Documentation/devicetree/bindings/media/i2c/ti,ds90ub960.yaml index 0b71e6f911a8..e17b508b6409 100644 --- a/Documentation/devicetree/bindings/media/i2c/ti,ds90ub960.yaml +++ b/Documentation/devicetree/bindings/media/i2c/ti,ds90ub960.yaml @@ -75,6 +75,13 @@ properties: address on the I2C bus where the deserializer resides are forwarded to the serializer. + i2c-addr: + $ref: /schemas/types.yaml#/definitions/uint32 + description: + The strap I2C address of the serializer. This is used by the + deserializer to internally communicate to the serializer over the + FPD-Link back-channel. + ti,rx-mode: $ref: /schemas/types.yaml#/definitions/uint32 enum: From patchwork Fri Jan 10 09:14:18 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tomi Valkeinen X-Patchwork-Id: 13934040 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 80BD120A5F3; Fri, 10 Jan 2025 09:15:44 +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=1736500546; cv=none; b=jGGLz6MHu8jgpdqwKs1tANncSo7+Cb57Q164OXGopKFbAiWQwqpZGTXFkbkEDDHX5ENT7ha8lSdbTZ9qWg03F8X2Pj28QQtyo+Mx2RzhiGvPe+tBDYbwD8Ue5meOREO8G8HllIldzvuO9v1lyXfnx66rlupLbP5bWiLqEzKbyZs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1736500546; c=relaxed/simple; bh=KdKGroifs831tSI8Vh8STKybkm+iASoe48SfOf8JeM4=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=QFbsdBMtog5d1/yJYqVeVoCdEKgH7DhKYAP48kTXr05g/uP/srjeyT5OdV19lI+MOaJIJee1oHYYd+kLyHxw4o3q+rdDmpLa6JJzRRChtmS4VDJQBJ7AqqtV6MhlIbj+YsOD5tRtNWTYX+UPFnjRjJG5YdnaYCkctiY5u7Hppa4= 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=h5q6Z6fF; 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="h5q6Z6fF" Received: from [127.0.1.1] (91-158-153-178.elisa-laajakaista.fi [91.158.153.178]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 7731C26A2; Fri, 10 Jan 2025 10:14:20 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1736500460; bh=KdKGroifs831tSI8Vh8STKybkm+iASoe48SfOf8JeM4=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=h5q6Z6fFhhLwKrHqvd37gPOY3jRPcov2NTMF3SwY+brlMtPbp5naTRsHAD/NC7kUx 2CEeB9BEPI1WcSR9kXQkovhJLLdP7eTFK1a1rdL07oaUwjjYjAIHy8dnb9Zbo4Z+9O DmpNiNqk7at/KScOfHQkFhSb59h1IY/KHHIq4LaE= From: Tomi Valkeinen Date: Fri, 10 Jan 2025 11:14:18 +0200 Subject: [PATCH 18/19] media: i2c: ds90ub960: Configure serializer using back-channel Precedence: bulk X-Mailing-List: linux-media@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20250110-ub9xx-improvements-v1-18-e0b9a1f644da@ideasonboard.com> References: <20250110-ub9xx-improvements-v1-0-e0b9a1f644da@ideasonboard.com> In-Reply-To: <20250110-ub9xx-improvements-v1-0-e0b9a1f644da@ideasonboard.com> To: Mauro Carvalho Chehab Cc: linux-media@vger.kernel.org, linux-kernel@vger.kernel.org, Devarsh Thakkar , Jai Luthra , Sakari Ailus , Tomi Valkeinen X-Mailer: b4 0.13.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=6543; i=tomi.valkeinen@ideasonboard.com; h=from:subject:message-id; bh=o25qM9tbApGD5KT0V52QfFJt1agsjTKsyXqEjqXOvxw=; b=owEBbQKS/ZANAwAIAfo9qoy8lh71AcsmYgBngOUXLkdO0bDxaRPAW3/aKYm0qbz4GarxKJ+8f vVaR34XjQ2JAjMEAAEIAB0WIQTEOAw+ll79gQef86f6PaqMvJYe9QUCZ4DlFwAKCRD6PaqMvJYe 9evsD/9zD6obQsMiRBp5L8qUVk0hZdublhPH/NBsrjLjzNzptrTvIdWWjujhyWeUhRJ5pA5mycH 4hyKNGwdSmHF2/W3mSq1W+G2tBpftJt0fkSZDtHZxba6uIGSZMcw6u90LbnnfolLKnjvSyAeqEg B8/7vBPHvr0Rzee5TmEmA5CTi34yRUmfNO6usUL4Yf+lORJ8Su0jd6FE8N64HjpaUn822MawqWm hea3gSUkrLC4wexF0HsBHmlOC0BLtcfpGx5ZwsGapcs5tt2EoWOJ8ikuXM3LRSBQNETjCVz5Se4 o+mntc9FqwNi0ftQzkhz/o3+QZCvlkIOdxAk2RXeUxMq78K5emiRT1OFzDcmfci09sUMCYEs2BC 0YvnxaXoL9nWPC8f22rFvYEU+CK1kpTuzIu2oiNenHR0a79LsCPavq4mqqGN8YfRpgS4n1F8Btb r3IYhW15yqcKq1BGA5lQPCp6Po9zAAlqgyu0pXnDgkGtEa6CSu24xVfLUCdMH/Il+Epd9gi4M1Z PtjCKDPhHPLfuCZwrrviQulz20vbTyZ7pXxAlt5ZhLFMnISm7Eu8/sHwFJU1vhzUoD3+sCB5YTj fK2SXD8/ZoQ5pgC3NIDJouInNS5bemOpH9bp762s9FM/Dc+4yy9lu7ousD3TxIEhru0yyrxnWL5 tajXhTWfwes8fqw== X-Developer-Key: i=tomi.valkeinen@ideasonboard.com; a=openpgp; fpr=C4380C3E965EFD81079FF3A7FA3DAA8CBC961EF5 From: Jai Luthra For DS90UB9702-Q1, it is recommended to configure some serializer settings over the back-channel before the forward-channel is active. This can only be done if the serializer's I2C address on the FPD-Link bus is populated in the device tree node. Signed-off-by: Jai Luthra Signed-off-by: Tomi Valkeinen --- drivers/media/i2c/ds90ub960.c | 124 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 120 insertions(+), 4 deletions(-) diff --git a/drivers/media/i2c/ds90ub960.c b/drivers/media/i2c/ds90ub960.c index a534d077f045..1ec3c060d4c6 100644 --- a/drivers/media/i2c/ds90ub960.c +++ b/drivers/media/i2c/ds90ub960.c @@ -248,13 +248,16 @@ MODULE_PARM_DESC(enable_sscg, "Enable SSCG (if available)"); #define UB960_RR_BCC_CONFIG 0x58 #define UB960_RR_BCC_CONFIG_BC_ALWAYS_ON BIT(4) +#define UB960_RR_BCC_CONFIG_AUTO_ACK_ALL BIT(5) #define UB960_RR_BCC_CONFIG_I2C_PASS_THROUGH BIT(6) #define UB960_RR_BCC_CONFIG_BC_FREQ_SEL_MASK GENMASK(2, 0) #define UB960_RR_DATAPATH_CTL1 0x59 #define UB960_RR_DATAPATH_CTL2 0x5a #define UB960_RR_SER_ID 0x5b +#define UB960_RR_SER_ID_FREEZE_DEVICE_ID BIT(0) #define UB960_RR_SER_ALIAS_ID 0x5c +#define UB960_RR_SER_ALIAS_ID_AUTO_ACK BIT(0) /* For these two register sets: n < UB960_MAX_PORT_ALIASES */ #define UB960_RR_SLAVE_ID(n) (0x5d + (n)) @@ -507,7 +510,9 @@ struct ub960_rxport { struct fwnode_handle *fwnode; struct i2c_client *client; unsigned short alias; /* I2C alias (lower 7 bits) */ + short addr; /* Local I2C address (lower 7 bits) */ struct ds90ub9xx_platform_data pdata; + struct regmap *regmap; } ser; enum ub960_rxport_mode rx_mode; @@ -2005,6 +2010,78 @@ static unsigned long ub960_calc_bc_clk_rate_ub9702(struct ub960_data *priv, } } +static int ub960_rxport_serializer_write(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; + int ret; + + if (err && *err) + return *err; + + data.byte = val; + + ret = i2c_smbus_xfer(priv->client->adapter, rxport->ser.alias, 0, + I2C_SMBUS_WRITE, reg, I2C_SMBUS_BYTE_DATA, &data); + if (ret) + dev_err(dev, + "rx%u: cannot write serializer register 0x%02x (%d)!\n", + rxport->nport, reg, ret); + + if (ret && err) + *err = ret; + + return ret; +} + +static int ub960_rxport_bc_ser_config(struct ub960_rxport *rxport) +{ + struct ub960_data *priv = rxport->priv; + struct device *dev = &priv->client->dev; + u8 nport = rxport->nport; + int ret; + + /* Skip port if serializer's address is not known */ + if (rxport->ser.addr < 0) { + dev_dbg(dev, + "rx%u: 'i2c-addr' property missing, skip serializer configuration\n", + nport); + return 0; + } + + /* + * Note: the code here probably only works for CSI-2 serializers in + * sync mode. To support other serializers the BC related configuration + * should be done before calling this function. + */ + + /* Enable 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, + UB960_RR_BCC_CONFIG_I2C_PASS_THROUGH | + UB960_RR_BCC_CONFIG_AUTO_ACK_ALL, + &ret); + + if (ret) + return ret; + + /* Disable BC alternate mode auto detect */ + ub960_rxport_serializer_write(rxport, 0x4b, 0x02, &ret); + /* Decrease link detect timer */ + ub960_rxport_serializer_write(rxport, 0x49, 0x06, &ret); + + /* 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_add_serializer(struct ub960_data *priv, u8 nport) { struct ub960_rxport *rxport = priv->rxports[nport]; @@ -2956,6 +3033,36 @@ static int ub960_init_rx_ports_ub9702(struct ub960_data *priv) if (ret) return ret; + for_each_active_rxport(priv) { + if (it.rxport->ser.addr >= 0) { + /* + * Set serializer's I2C address if set in the dts file, + * and freeze it to prevent updates from the FC. + */ + ub960_rxport_write(priv, it.nport, UB960_RR_SER_ID, + it.rxport->ser.addr << 1 | + UB960_RR_SER_ID_FREEZE_DEVICE_ID, + &ret); + } + + /* Set serializer I2C alias with auto-ack */ + ub960_rxport_write(priv, it.nport, UB960_RR_SER_ALIAS_ID, + it.rxport->ser.alias << 1 | + UB960_RR_SER_ALIAS_ID_AUTO_ACK, &ret); + + if (ret) + return ret; + } + + for_each_active_rxport(priv) { + if (fwnode_device_is_compatible(it.rxport->ser.fwnode, + "ti,ds90ub971-q1")) { + ret = ub960_rxport_bc_ser_config(it.rxport); + if (ret) + return ret; + } + } + if (ub960_enable_sscg) { ret = ub960_enable_sscg_ub9702(priv); if (ret) @@ -3090,16 +3197,17 @@ static int ub960_init_rx_ports_ub9702(struct ub960_data *priv) ub960_rxport_write(priv, it.nport, UB960_RR_PORT_ICR_LO, 0x7f, &ret); + /* Clear serializer I2C alias auto-ack */ + ub960_rxport_update_bits(priv, it.nport, UB960_RR_SER_ALIAS_ID, + UB960_RR_SER_ALIAS_ID_AUTO_ACK, 0, + &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; } @@ -4258,6 +4366,7 @@ ub960_parse_dt_rxport_link_properties(struct ub960_data *priv, s32 strobe_pos; u32 eq_level; u32 ser_i2c_alias; + u32 ser_i2c_addr; int ret; cdr_mode = RXPORT_CDR_FPD3; @@ -4363,6 +4472,13 @@ ub960_parse_dt_rxport_link_properties(struct ub960_data *priv, } rxport->ser.alias = ser_i2c_alias; + ret = fwnode_property_read_u32(link_fwnode, "i2c-addr", + &ser_i2c_addr); + if (ret) + rxport->ser.addr = -EINVAL; + else + rxport->ser.addr = ser_i2c_addr; + rxport->ser.fwnode = fwnode_get_named_child_node(link_fwnode, "serializer"); if (!rxport->ser.fwnode) { dev_err(dev, "rx%u: missing 'serializer' node\n", nport); From patchwork Fri Jan 10 09:14:19 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tomi Valkeinen X-Patchwork-Id: 13934041 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 7F39D20E03B; Fri, 10 Jan 2025 09:15:45 +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=1736500547; cv=none; b=VdrFU00nfJSmZ125ZZEf6cTIIpehjvZ6Qm6auuEJzmytShovyvH2XAu7T0q75t83AYeTWlSBVdB5RudICRmGnrWLKvF0Zlhe3yY5SM7ET9GtVQGMj+iTfiugZ3ze+JtOeiob0fllqGNJ16U0XLzsjrPid5oLkpTOFB9jL/nOvE0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1736500547; c=relaxed/simple; bh=xENFn0j7WKkzC+GeAFdGiwux+LBDvFMD326jlfn1Wbo=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=hFfV31nl5aJo+FQpU614M3xpLp1Bi1+ADAv72g7rY7aY2hdpE6zDiy78H8ZNKPjfqjS0qImA4altjMgBfdKOoDsmZ1CdLKL7GHUWOg0w1rFKJbUvsNtCEk8vfPoTmL+EZ4FP3foATTLk4CgcT3bX4i9au70Ets3EQuGQ0T58xQ0= 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=NQ5V5/gD; 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="NQ5V5/gD" Received: from [127.0.1.1] (91-158-153-178.elisa-laajakaista.fi [91.158.153.178]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 06E4326A3; Fri, 10 Jan 2025 10:14:20 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1736500461; bh=xENFn0j7WKkzC+GeAFdGiwux+LBDvFMD326jlfn1Wbo=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=NQ5V5/gDEKN402IqBB4sDO9rW1RCHvbF7tZhncJ0mnbNZFBBjS4UmcSpHv0Oy9tQW jQ1ifOy8DyO9FuK1jsWrv/chkl92BAbhcrZGWMWIhlj36NxQULkgJIne4s8EJPQoDW N1l9ZYqgy2tGaaxbS3sqV1PVWjPtRHrZg6dARgwY= From: Tomi Valkeinen Date: Fri, 10 Jan 2025 11:14:19 +0200 Subject: [PATCH 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: <20250110-ub9xx-improvements-v1-19-e0b9a1f644da@ideasonboard.com> References: <20250110-ub9xx-improvements-v1-0-e0b9a1f644da@ideasonboard.com> In-Reply-To: <20250110-ub9xx-improvements-v1-0-e0b9a1f644da@ideasonboard.com> To: Mauro Carvalho Chehab Cc: linux-media@vger.kernel.org, linux-kernel@vger.kernel.org, Devarsh Thakkar , Jai Luthra , Sakari Ailus , Tomi Valkeinen X-Mailer: b4 0.13.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=7480; i=tomi.valkeinen@ideasonboard.com; h=from:subject:message-id; bh=j8VGR+q9mnFLoJmhSBGzWeDaLhfWfz5KiFjXcez6K8o=; b=owEBbQKS/ZANAwAIAfo9qoy8lh71AcsmYgBngOUXIjMNcAZG0fOOpyWxCZgqAkESM1i10Te/4 MKhe6/llsOJAjMEAAEIAB0WIQTEOAw+ll79gQef86f6PaqMvJYe9QUCZ4DlFwAKCRD6PaqMvJYe 9WWvD/9foVh0T4uzHHcItQeYVxUAxOKhnGdHgf2DmB9xeHVTkDsZrXsWGBfwmgJawJCZll+Yefe TGhk7wdqT19hWVn0kurlskTt//Y+f7c4Hu482MAC+XYxdFDmfo0LpHNlv7jFcm5bfSjGKJQ5isq 7f31BKQsfclEUc56fok9GIOCrVhw26GJhehIpdyppv8xAUr755M3CyINBrc1RPb9x2g+4a3biJx +9liO+DDQ+OioYWix2iegfiq2OBCM1no3AEGA435yKjK1tjL+1f5SxcecdIOp41xrD7yrDh+Kx/ fnr+ehOYXwmPyKBV4s1ovBce5jyyMoOG8e/xl0Sw7+J+ICuAh1r/09yKW5rcIdWNtqbL0XaWBO3 Hm1dQxckmwvnMU0/uuPPJ2TGMUlsfzIEc75pfVNcleXwvGX4Rj9jgl6apM6qUG9NYx0dSbVfvp3 0shla8ewqN29LpxTctP5rEvg0p9IgQAl2UFtbsLQlz/ylDSIpCe0EdDnU6I2Ju2rbzJQN+Kv/0B tIjqeEsbBZ9xAQRoLMGPsa2/Fx/2ZGKVVN2RKPyhfPGpxBc4EcfK3R9LWfU4RfQJXK0VHZVpLLB dFfXE7Z7PRWMSc1vQIPIg8t2y7SDXk+XHXf9vsoa9KE/St4IoW46/TewJ8i44+6VUwTt9EN7Oq7 7QXeuBcf3Pf5fcw== X-Developer-Key: i=tomi.valkeinen@ideasonboard.com; a=openpgp; fpr=C4380C3E965EFD81079FF3A7FA3DAA8CBC961EF5 From: Jai Luthra 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 Signed-off-by: Tomi Valkeinen --- drivers/media/i2c/ds90ub953.c | 9 --- drivers/media/i2c/ds90ub960.c | 125 ++++++++++++++++++++++++++++++++++++++++++ include/media/i2c/ds90ub9xx.h | 15 +++++ 3 files changed, 140 insertions(+), 9 deletions(-) diff --git a/drivers/media/i2c/ds90ub953.c b/drivers/media/i2c/ds90ub953.c index 6c36980e8beb..bba8be031032 100644 --- a/drivers/media/i2c/ds90ub953.c +++ b/drivers/media/i2c/ds90ub953.c @@ -35,10 +35,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 @@ -92,16 +88,11 @@ #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 diff --git a/drivers/media/i2c/ds90ub960.c b/drivers/media/i2c/ds90ub960.c index 1ec3c060d4c6..6daf760f394b 100644 --- a/drivers/media/i2c/ds90ub960.c +++ b/drivers/media/i2c/ds90ub960.c @@ -2036,6 +2036,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; @@ -2415,6 +2519,20 @@ static int ub960_init_rx_ports_ub960(struct ub960_data *priv) return ret; } + /* Set temperature ramp on serializer */ + for_each_active_rxport(priv) { + 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. @@ -3171,6 +3289,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) { + ret = ub960_serializer_temp_ramp(it.rxport); + if (ret) + return ret; + } + for_each_active_rxport_fpd4(priv) { ret = ub960_enable_dfe_lms_ub9702(priv, it.nport); if (ret) diff --git a/include/media/i2c/ds90ub9xx.h b/include/media/i2c/ds90ub9xx.h index 0245198469ec..d803af07cabc 100644 --- a/include/media/i2c/ds90ub9xx.h +++ b/include/media/i2c/ds90ub9xx.h @@ -5,6 +5,21 @@ #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_IND_ACC_CTL 0xb0 +#define UB953_REG_IND_ACC_ADDR 0xb1 +#define UB953_REG_IND_ACC_DATA 0xb2 + +#define UB953_IND_TARGET_ANALOG 0x01 + +#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) + struct i2c_atr; /**