All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v8 0/7] i2c-atr and FPDLink
@ 2023-01-20 15:34 Tomi Valkeinen
  2023-01-20 15:34 ` [PATCH v8 1/7] i2c: add I2C Address Translator (ATR) support Tomi Valkeinen
                   ` (7 more replies)
  0 siblings, 8 replies; 16+ messages in thread
From: Tomi Valkeinen @ 2023-01-20 15:34 UTC (permalink / raw)
  To: linux-media, devicetree, linux-kernel, linux-i2c, Rob Herring,
	Krzysztof Kozlowski, Wolfram Sang, Luca Ceresoli,
	Andy Shevchenko, Matti Vaittinen, Laurent Pinchart
  Cc: Mauro Carvalho Chehab, Peter Rosin, Liam Girdwood, Mark Brown,
	Sakari Ailus, Michael Tretter, Shawn Tu, Hans Verkuil,
	Mike Pagano, Krzysztof Hałasa, Marek Vasut,
	Satish Nagireddy, Tomi Valkeinen

Hi,

You can find v7 from:

https://lore.kernel.org/all/20230118124031.788940-1-tomi.valkeinen@ideasonboard.com/

Diff to v7 included below.

Main changes in v8:
- Added missing 'link-frequencies' to ti,ds90ub960.yaml
- Dropped ATR select/deselect ops
- Don't use devm_kzalloc() in i2c_atr_new()
- Fixed the reported error handling paths (mainly adding
  fwnode_handle_puts)
- Dropped all WARNs
- Plenty of cosmetic/style changes

I saw the suggestion to change the i2c_atr to be embedded in the main
driver's private data struct. That change has not been done in this
version.

 Tomi

Luca Ceresoli (1):
  i2c: add I2C Address Translator (ATR) support

Tomi Valkeinen (6):
  dt-bindings: media: add TI DS90UB913 FPD-Link III Serializer
  dt-bindings: media: add TI DS90UB953 FPD-Link III Serializer
  dt-bindings: media: add TI DS90UB960 FPD-Link III Deserializer
  media: i2c: add DS90UB960 driver
  media: i2c: add DS90UB913 driver
  media: i2c: add DS90UB953 driver

 .../bindings/media/i2c/ti,ds90ub913.yaml      |  133 +
 .../bindings/media/i2c/ti,ds90ub953.yaml      |  134 +
 .../bindings/media/i2c/ti,ds90ub960.yaml      |  431 ++
 Documentation/i2c/index.rst                   |    1 +
 Documentation/i2c/muxes/i2c-atr.rst           |   83 +
 MAINTAINERS                                   |   16 +
 drivers/i2c/Kconfig                           |    9 +
 drivers/i2c/Makefile                          |    1 +
 drivers/i2c/i2c-atr.c                         |  532 ++
 drivers/media/i2c/Kconfig                     |   47 +
 drivers/media/i2c/Makefile                    |    3 +
 drivers/media/i2c/ds90ub913.c                 |  851 ++++
 drivers/media/i2c/ds90ub953.c                 | 1572 ++++++
 drivers/media/i2c/ds90ub960.c                 | 4278 +++++++++++++++++
 include/linux/i2c-atr.h                       |  113 +
 include/media/i2c/ds90ub9xx.h                 |   16 +
 16 files changed, 8220 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/media/i2c/ti,ds90ub913.yaml
 create mode 100644 Documentation/devicetree/bindings/media/i2c/ti,ds90ub953.yaml
 create mode 100644 Documentation/devicetree/bindings/media/i2c/ti,ds90ub960.yaml
 create mode 100644 Documentation/i2c/muxes/i2c-atr.rst
 create mode 100644 drivers/i2c/i2c-atr.c
 create mode 100644 drivers/media/i2c/ds90ub913.c
 create mode 100644 drivers/media/i2c/ds90ub953.c
 create mode 100644 drivers/media/i2c/ds90ub960.c
 create mode 100644 include/linux/i2c-atr.h
 create mode 100644 include/media/i2c/ds90ub9xx.h

Interdiff against v7:
diff --git a/Documentation/devicetree/bindings/media/i2c/ti,ds90ub960.yaml b/Documentation/devicetree/bindings/media/i2c/ti,ds90ub960.yaml
index 1ba22450cdba..bb921caa85a7 100644
--- a/Documentation/devicetree/bindings/media/i2c/ti,ds90ub960.yaml
+++ b/Documentation/devicetree/bindings/media/i2c/ti,ds90ub960.yaml
@@ -190,9 +190,12 @@ properties:
               data-lanes:
                 minItems: 1
                 maxItems: 4
+              link-frequencies:
+                maxItems: 1
 
             required:
               - data-lanes
+              - link-frequencies
 
       port@5:
         $ref: /schemas/graph.yaml#/$defs/port-base
@@ -208,9 +211,12 @@ properties:
               data-lanes:
                 minItems: 1
                 maxItems: 4
+              link-frequencies:
+                maxItems: 1
 
             required:
               - data-lanes
+              - link-frequencies
 
     required:
       - port@0
@@ -273,12 +279,12 @@ examples:
             };
           };
 
-          /* Port 2, unused */
+          /* Port 2, unconnected */
           port@2 {
             reg = <2>;
           };
 
-          /* Port 3, unused */
+          /* Port 3, unconnected */
           port@3 {
             reg = <3>;
           };
@@ -293,7 +299,7 @@ examples:
             };
           };
 
-          /* Port 5, unused */
+          /* Port 5, unconnected */
           port@5 {
             reg = <5>;
           };
diff --git a/drivers/i2c/i2c-atr.c b/drivers/i2c/i2c-atr.c
index 1d43cf3824eb..c872647ae808 100644
--- a/drivers/i2c/i2c-atr.c
+++ b/drivers/i2c/i2c-atr.c
@@ -16,8 +16,8 @@
 #include <linux/mutex.h>
 #include <linux/slab.h>
 
-#define ATR_MAX_ADAPTERS 99	/* Just a sanity limit */
-#define ATR_MAX_SYMLINK_LEN 16	/* Longest name is 10 chars: "channel-99" */
+#define ATR_MAX_ADAPTERS 100	/* Just a sanity limit */
+#define ATR_MAX_SYMLINK_LEN 11	/* Longest name is 10 chars: "channel-99" */
 
 /**
  * struct i2c_atr_cli2alias_pair - Holds the alias assigned to a client.
@@ -179,18 +179,12 @@ static int i2c_atr_master_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
 	struct i2c_adapter *parent = atr->parent;
 	int ret;
 
-	/* Switch to the right atr port */
-	if (atr->ops->select) {
-		ret = atr->ops->select(atr, chan->chan_id);
-		if (ret < 0)
-			goto out_deselect;
-	}
-
 	/* Translate addresses */
 	mutex_lock(&chan->orig_addrs_lock);
+
 	ret = i2c_atr_map_msgs(chan, msgs, num);
 	if (ret < 0)
-		goto out_unlock_deselect;
+		goto err_unlock;
 
 	/* Perform the transfer */
 	ret = i2c_transfer(parent, msgs, num);
@@ -198,13 +192,9 @@ static int i2c_atr_master_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
 	/* Restore addresses */
 	i2c_atr_unmap_msgs(chan, msgs, num);
 
-out_unlock_deselect:
+err_unlock:
 	mutex_unlock(&chan->orig_addrs_lock);
 
-out_deselect:
-	if (atr->ops->deselect)
-		atr->ops->deselect(atr, chan->chan_id);
-
 	return ret;
 }
 
@@ -216,7 +206,6 @@ static int i2c_atr_smbus_xfer(struct i2c_adapter *adap, u16 addr,
 	struct i2c_atr *atr = chan->atr;
 	struct i2c_adapter *parent = atr->parent;
 	struct i2c_atr_cli2alias_pair *c2a;
-	int ret = 0;
 
 	c2a = i2c_atr_find_mapping_by_addr(&chan->alias_list, addr);
 	if (!c2a) {
@@ -224,15 +213,8 @@ static int i2c_atr_smbus_xfer(struct i2c_adapter *adap, u16 addr,
 		return -ENXIO;
 	}
 
-	if (atr->ops->select)
-		ret = atr->ops->select(atr, chan->chan_id);
-	if (!ret)
-		ret = i2c_smbus_xfer(parent, c2a->alias, flags, read_write,
-				     command, size, data);
-	if (atr->ops->deselect)
-		atr->ops->deselect(atr, chan->chan_id);
-
-	return ret;
+	return i2c_smbus_xfer(parent, c2a->alias, flags, read_write, command,
+			      size, data);
 }
 
 static u32 i2c_atr_functionality(struct i2c_adapter *adap)
@@ -372,8 +354,7 @@ struct i2c_atr *i2c_atr_new(struct i2c_adapter *parent, struct device *dev,
 	if (!ops || !ops->attach_client || !ops->detach_client)
 		return ERR_PTR(-EINVAL);
 
-	atr = devm_kzalloc(dev, struct_size(atr, adapter, max_adapters),
-			   GFP_KERNEL);
+	atr = kzalloc(struct_size(atr, adapter, max_adapters), GFP_KERNEL);
 	if (!atr)
 		return ERR_PTR(-ENOMEM);
 
@@ -405,6 +386,7 @@ void i2c_atr_delete(struct i2c_atr *atr)
 {
 	bus_unregister_notifier(&i2c_bus_type, &atr->i2c_nb);
 	mutex_destroy(&atr->lock);
+	kfree(atr);
 }
 EXPORT_SYMBOL_NS_GPL(i2c_atr_delete, I2C_ATR);
 
@@ -502,15 +484,18 @@ EXPORT_SYMBOL_NS_GPL(i2c_atr_add_adapter, I2C_ATR);
 void i2c_atr_del_adapter(struct i2c_atr *atr, u32 chan_id)
 {
 	char symlink_name[ATR_MAX_SYMLINK_LEN];
-
-	struct i2c_adapter *adap = atr->adapter[chan_id];
-	struct i2c_atr_chan *chan = adap->algo_data;
-	struct fwnode_handle *fwnode = dev_fwnode(&adap->dev);
+	struct i2c_adapter *adap;
+	struct i2c_atr_chan *chan;
+	struct fwnode_handle *fwnode;
 	struct device *dev = atr->dev;
 
+	adap = atr->adapter[chan_id];
 	if (!adap)
 		return;
 
+	chan = adap->algo_data;
+	fwnode = dev_fwnode(&adap->dev);
+
 	dev_dbg(dev, "Removing ATR child bus %d\n", i2c_adapter_id(adap));
 
 	snprintf(symlink_name, sizeof(symlink_name), "channel-%u",
diff --git a/drivers/media/i2c/ds90ub913.c b/drivers/media/i2c/ds90ub913.c
index befa78128a9a..60a07b5bace3 100644
--- a/drivers/media/i2c/ds90ub913.c
+++ b/drivers/media/i2c/ds90ub913.c
@@ -337,7 +337,7 @@ static int ub913_get_frame_desc(struct v4l2_subdev *sd, unsigned int pad,
 			dev_err(&priv->client->dev,
 				"Failed to find stream from source frame desc\n");
 			ret = -EPIPE;
-			goto out;
+			goto out_unlock;
 		}
 
 		fd->entry[fd->num_entries].stream = route->source_stream;
@@ -349,7 +349,7 @@ static int ub913_get_frame_desc(struct v4l2_subdev *sd, unsigned int pad,
 		fd->num_entries++;
 	}
 
-out:
+out_unlock:
 	v4l2_subdev_unlock_state(state);
 
 	return ret;
@@ -626,7 +626,7 @@ static int ub913_parse_dt(struct ub913_data *priv)
 	ep_fwnode = fwnode_graph_get_endpoint_by_id(dev_fwnode(dev),
 						    UB913_PAD_SINK, 0, 0);
 	if (!ep_fwnode) {
-		dev_err(dev, "No sink endpoint\n");
+		dev_err_probe(dev, -ENOENT, "No sink endpoint\n");
 		return -ENOENT;
 	}
 
@@ -636,7 +636,7 @@ static int ub913_parse_dt(struct ub913_data *priv)
 	fwnode_handle_put(ep_fwnode);
 
 	if (ret) {
-		dev_err(dev, "OF: failed to parse pclk-sample: %d\n", ret);
+		dev_err_probe(dev, ret, "failed to parse 'pclk-sample'\n");
 		return ret;
 	}
 
@@ -706,7 +706,7 @@ static int ub913_subdev_init(struct ub913_data *priv)
 
 	ret = v4l2_subdev_init_finalize(&priv->sd);
 	if (ret)
-		goto err_entity_cleanup;
+		goto err_fwnode_put;
 
 	ret = ub913_v4l2_notifier_register(priv);
 	if (ret) {
@@ -727,6 +727,8 @@ static int ub913_subdev_init(struct ub913_data *priv)
 	ub913_v4l2_nf_unregister(priv);
 err_subdev_cleanup:
 	v4l2_subdev_cleanup(&priv->sd);
+err_fwnode_put:
+	fwnode_handle_put(priv->sd.fwnode);
 err_entity_cleanup:
 	media_entity_cleanup(&priv->sd.entity);
 
@@ -738,6 +740,7 @@ static void ub913_subdev_uninit(struct ub913_data *priv)
 	v4l2_async_unregister_subdev(&priv->sd);
 	ub913_v4l2_nf_unregister(priv);
 	v4l2_subdev_cleanup(&priv->sd);
+	fwnode_handle_put(priv->sd.fwnode);
 	media_entity_cleanup(&priv->sd.entity);
 }
 
@@ -764,7 +767,7 @@ static int ub913_probe(struct i2c_client *client)
 
 	/*
 	 * ub913 can also work without ext clock, but that is not supported by
-	 * the driver yet
+	 * the driver yet.
 	 */
 	priv->clkin = devm_clk_get(dev, "clkin");
 	if (IS_ERR(priv->clkin))
diff --git a/drivers/media/i2c/ds90ub953.c b/drivers/media/i2c/ds90ub953.c
index ec33e16da3d1..738652f2294b 100644
--- a/drivers/media/i2c/ds90ub953.c
+++ b/drivers/media/i2c/ds90ub953.c
@@ -18,7 +18,6 @@
 #include <linux/kernel.h>
 #include <linux/math64.h>
 #include <linux/module.h>
-#include <linux/of_device.h>
 #include <linux/property.h>
 #include <linux/rational.h>
 #include <linux/regmap.h>
@@ -52,8 +51,8 @@
 #define UB953_REG_CLKOUT_CTRL0			0x06
 #define UB953_REG_CLKOUT_CTRL1			0x07
 
-#define UB953_REG_SCL_HIGH_TIME			0x0B
-#define UB953_REG_SCL_LOW_TIME			0x0C
+#define UB953_REG_SCL_HIGH_TIME			0x0b
+#define UB953_REG_SCL_LOW_TIME			0x0c
 
 #define UB953_REG_LOCAL_GPIO_DATA		0x0d
 #define UB953_REG_LOCAL_GPIO_DATA_GPIO_RMTEN(n)		BIT(4 + (n))
@@ -74,9 +73,9 @@
 #define UB953_REG_CRC_ERR_CNT2			0x56
 
 #define UB953_REG_CSI_ERR_CNT			0x5c
-#define UB953_REG_CSI_ERR_STATUS		0x5D
-#define UB953_REG_CSI_ERR_DLANE01		0x5E
-#define UB953_REG_CSI_ERR_DLANE23		0x5F
+#define UB953_REG_CSI_ERR_STATUS		0x5d
+#define UB953_REG_CSI_ERR_DLANE01		0x5e
+#define UB953_REG_CSI_ERR_DLANE23		0x5f
 #define UB953_REG_CSI_ERR_CLK_LANE		0x60
 #define UB953_REG_CSI_PKT_HDR_VC_ID		0x61
 #define UB953_REG_PKT_HDR_WC_LSB		0x62
@@ -104,12 +103,12 @@
 #define UB953_IND_PGEN_BAR_SIZE0		0x07
 #define UB953_IND_PGEN_ACT_LPF1			0x08
 #define UB953_IND_PGEN_ACT_LPF0			0x09
-#define UB953_IND_PGEN_TOT_LPF1			0x0A
-#define UB953_IND_PGEN_TOT_LPF0			0x0B
-#define UB953_IND_PGEN_LINE_PD1			0x0C
-#define UB953_IND_PGEN_LINE_PD0			0x0D
-#define UB953_IND_PGEN_VBP			0x0E
-#define UB953_IND_PGEN_VFP			0x0F
+#define UB953_IND_PGEN_TOT_LPF1			0x0a
+#define UB953_IND_PGEN_TOT_LPF0			0x0b
+#define UB953_IND_PGEN_LINE_PD1			0x0c
+#define UB953_IND_PGEN_LINE_PD0			0x0d
+#define UB953_IND_PGEN_VBP			0x0e
+#define UB953_IND_PGEN_VFP			0x0f
 #define UB953_IND_PGEN_COLOR(n)			(0x10 + (n)) /* n <= 15 */
 
 /* Note: Only sync mode supported for now */
@@ -160,7 +159,7 @@ struct ub953_data {
 
 	enum ub953_mode		mode;
 
-	struct ds90ub9xx_platform_data *plat_data;
+	const struct ds90ub9xx_platform_data	*plat_data;
 };
 
 static inline struct ub953_data *sd_to_ub953(struct v4l2_subdev *sd)
@@ -180,12 +179,15 @@ static int ub953_read(struct ub953_data *priv, u8 reg, u8 *val)
 	mutex_lock(&priv->reg_lock);
 
 	ret = regmap_read(priv->regmap, reg, &v);
-	if (ret)
+	if (ret) {
 		dev_err(&priv->client->dev, "Cannot read register 0x%02x: %d\n",
 			reg, ret);
-	else
-		*val = v;
+		goto out_unlock;
+	}
 
+	*val = v;
+
+out_unlock:
 	mutex_unlock(&priv->reg_lock);
 
 	return ret;
@@ -207,7 +209,7 @@ static int ub953_write(struct ub953_data *priv, u8 reg, u8 val)
 	return ret;
 }
 
-static int _ub953_select_ind_reg_block(struct ub953_data *priv, u8 block)
+static int ub953_select_ind_reg_block(struct ub953_data *priv, u8 block)
 {
 	struct device *dev = &priv->client->dev;
 	int ret;
@@ -235,16 +237,16 @@ __maybe_unused static int ub953_read_ind(struct ub953_data *priv, u8 block,
 
 	mutex_lock(&priv->reg_lock);
 
-	ret = _ub953_select_ind_reg_block(priv, block);
+	ret = ub953_select_ind_reg_block(priv, block);
 	if (ret)
-		goto out;
+		goto out_unlock;
 
 	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",
 			block, reg, ret);
-		goto out;
+		goto out_unlock;
 	}
 
 	ret = regmap_read(priv->regmap, UB953_REG_IND_ACC_DATA, &v);
@@ -252,12 +254,12 @@ __maybe_unused static int ub953_read_ind(struct ub953_data *priv, u8 block,
 		dev_err(&priv->client->dev,
 			"Write to IND_ACC_DATA failed when reading %u:%x02x: %d\n",
 			block, reg, ret);
-		goto out;
+		goto out_unlock;
 	}
 
 	*val = v;
 
-out:
+out_unlock:
 	mutex_unlock(&priv->reg_lock);
 
 	return ret;
@@ -269,16 +271,16 @@ static int ub953_write_ind(struct ub953_data *priv, u8 block, u8 reg, u8 val)
 
 	mutex_lock(&priv->reg_lock);
 
-	ret = _ub953_select_ind_reg_block(priv, block);
+	ret = ub953_select_ind_reg_block(priv, block);
 	if (ret)
-		goto out;
+		goto out_unlock;
 
 	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",
 			block, reg, ret);
-		goto out;
+		goto out_unlock;
 	}
 
 	ret = regmap_write(priv->regmap, UB953_REG_IND_ACC_DATA, val);
@@ -288,7 +290,7 @@ static int ub953_write_ind(struct ub953_data *priv, u8 block, u8 reg, u8 val)
 			block, reg, ret);
 	}
 
-out:
+out_unlock:
 	mutex_unlock(&priv->reg_lock);
 
 	return ret;
@@ -300,27 +302,27 @@ static int ub953_write_ind16(struct ub953_data *priv, u8 block, u8 reg, u16 val)
 
 	mutex_lock(&priv->reg_lock);
 
-	ret = _ub953_select_ind_reg_block(priv, block);
+	ret = ub953_select_ind_reg_block(priv, block);
 	if (ret)
-		goto out;
+		goto out_unlock;
 
 	ret = regmap_write(priv->regmap, UB953_REG_IND_ACC_ADDR, reg);
 	if (ret)
-		goto out;
+		goto out_unlock;
 
 	ret = regmap_write(priv->regmap, UB953_REG_IND_ACC_DATA, val >> 8);
 	if (ret)
-		goto out;
+		goto out_unlock;
 
 	ret = regmap_write(priv->regmap, UB953_REG_IND_ACC_ADDR, reg + 1);
 	if (ret)
-		goto out;
+		goto out_unlock;
 
 	ret = regmap_write(priv->regmap, UB953_REG_IND_ACC_DATA, val & 0xff);
 	if (ret)
-		goto out;
+		goto out_unlock;
 
-out:
+out_unlock:
 	mutex_unlock(&priv->reg_lock);
 
 	return ret;
@@ -503,7 +505,6 @@ static int ub953_get_frame_desc(struct v4l2_subdev *sd, unsigned int pad,
 				struct v4l2_mbus_frame_desc *fd)
 {
 	struct ub953_data *priv = sd_to_ub953(sd);
-	const struct v4l2_subdev_krouting *routing;
 	struct v4l2_mbus_frame_desc source_fd;
 	struct v4l2_subdev_route *route;
 	struct v4l2_subdev_state *state;
@@ -523,9 +524,7 @@ static int ub953_get_frame_desc(struct v4l2_subdev *sd, unsigned int pad,
 
 	state = v4l2_subdev_lock_and_get_active_state(sd);
 
-	routing = &state->routing;
-
-	for_each_active_route(routing, route) {
+	for_each_active_route(&state->routing, route) {
 		struct v4l2_mbus_frame_desc_entry *source_entry = NULL;
 		unsigned int i;
 
@@ -543,7 +542,7 @@ static int ub953_get_frame_desc(struct v4l2_subdev *sd, unsigned int pad,
 			dev_err(&priv->client->dev,
 				"Failed to find stream from source frame desc\n");
 			ret = -EPIPE;
-			goto out;
+			goto out_unlock;
 		}
 
 		fd->entry[fd->num_entries].stream = route->source_stream;
@@ -558,7 +557,7 @@ static int ub953_get_frame_desc(struct v4l2_subdev *sd, unsigned int pad,
 		fd->num_entries++;
 	}
 
-out:
+out_unlock:
 	v4l2_subdev_unlock_state(state);
 
 	return ret;
@@ -1268,25 +1267,20 @@ static int ub953_parse_dt(struct ub953_data *priv)
 
 	ep_fwnode = fwnode_graph_get_endpoint_by_id(dev_fwnode(dev),
 						    UB953_PAD_SINK, 0, 0);
-	if (!ep_fwnode) {
-		dev_err(dev, "OF: no endpoint\n");
-		return -ENOENT;
-	}
+	if (!ep_fwnode)
+		return dev_err_probe(dev, -ENOENT, "no endpoint found\n");
 
 	ret = fwnode_property_count_u32(ep_fwnode, "data-lanes");
 
 	fwnode_handle_put(ep_fwnode);
 
-	if (ret <= 0) {
-		dev_err(dev, "failed to parse property 'data-lanes': %d\n",
-			ret);
-		return ret;
-	}
+	if (ret < 0)
+		return dev_err_probe(dev, ret,
+				     "failed to parse property 'data-lanes'\n");
 
-	if (ret != 1 && ret != 2 && ret != 4) {
-		dev_err(dev, "bad number of data-lanes: %d\n", ret);
-		return -EINVAL;
-	}
+	if (ret != 1 && ret != 2 && ret != 4)
+		return dev_err_probe(dev, -EINVAL,
+				     "bad number of data-lanes: %d\n", ret);
 
 	priv->num_data_lanes = ret;
 
@@ -1324,7 +1318,7 @@ static int ub953_hw_init(struct ub953_data *priv)
 		break;
 	default:
 		return dev_err_probe(dev, -EIO,
-				     "Illegal mode in mode register\n");
+				     "Invalid mode in mode register\n");
 	}
 
 	dev_dbg(dev, "mode from %s: %#x\n", mode_override ? "reg" : "strap",
@@ -1366,8 +1360,7 @@ static int ub953_subdev_init(struct ub953_data *priv)
 
 	v4l2_i2c_subdev_init(&priv->sd, priv->client, &ub953_subdev_ops);
 
-	v4l2_ctrl_handler_init(&priv->ctrl_handler,
-			       ARRAY_SIZE(ub953_tpg_qmenu) - 1);
+	v4l2_ctrl_handler_init(&priv->ctrl_handler, 1);
 	priv->sd.ctrl_handler = &priv->ctrl_handler;
 
 	v4l2_ctrl_new_std_menu_items(&priv->ctrl_handler, &ub953_ctrl_ops,
@@ -1375,9 +1368,11 @@ static int ub953_subdev_init(struct ub953_data *priv)
 				     ARRAY_SIZE(ub953_tpg_qmenu) - 1, 0, 0,
 				     ub953_tpg_qmenu);
 
-	if (priv->ctrl_handler.error)
-		return dev_err_probe(dev, priv->ctrl_handler.error,
-				     "Failed to set up v4l2 controls\n");
+	if (priv->ctrl_handler.error) {
+		ret = priv->ctrl_handler.error;
+		dev_err_probe(dev, ret, "Failed to set up v4l2 controls\n");
+		goto err_remove_ctrls;
+	}
 
 	priv->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE |
 			  V4L2_SUBDEV_FL_HAS_EVENTS | V4L2_SUBDEV_FL_STREAMS;
@@ -1406,7 +1401,7 @@ static int ub953_subdev_init(struct ub953_data *priv)
 
 	ret = v4l2_subdev_init_finalize(&priv->sd);
 	if (ret)
-		goto err_entity_cleanup;
+		goto err_fwnode_put;
 
 	ret = ub953_v4l2_notifier_register(priv);
 	if (ret) {
@@ -1427,6 +1422,8 @@ static int ub953_subdev_init(struct ub953_data *priv)
 	ub953_v4l2_notifier_unregister(priv);
 err_free_state:
 	v4l2_subdev_cleanup(&priv->sd);
+err_fwnode_put:
+	fwnode_handle_put(priv->sd.fwnode);
 err_entity_cleanup:
 	media_entity_cleanup(&priv->sd.entity);
 err_remove_ctrls:
@@ -1440,6 +1437,7 @@ static void ub953_subdev_uninit(struct ub953_data *priv)
 	v4l2_async_unregister_subdev(&priv->sd);
 	ub953_v4l2_notifier_unregister(priv);
 	v4l2_subdev_cleanup(&priv->sd);
+	fwnode_handle_put(priv->sd.fwnode);
 	media_entity_cleanup(&priv->sd.entity);
 	v4l2_ctrl_handler_free(&priv->ctrl_handler);
 }
@@ -1456,9 +1454,7 @@ static int ub953_probe(struct i2c_client *client)
 
 	priv->client = client;
 
-	priv->hw_data = of_device_get_match_data(dev);
-	if (!priv->hw_data)
-		return -ENODEV;
+	priv->hw_data = device_get_match_data(dev);
 
 	priv->plat_data = dev_get_platdata(&client->dev);
 	if (!priv->plat_data)
@@ -1544,8 +1540,8 @@ static const struct ub953_hw_data ds90ub971_hw = {
 };
 
 static const struct i2c_device_id ub953_id[] = {
-	{ "ds90ub953-q1", 0 },
-	{ "ds90ub971-q1", 0 },
+	{ "ds90ub953-q1", (kernel_ulong_t)&ds90ub953_hw },
+	{ "ds90ub971-q1", (kernel_ulong_t)&ds90ub971_hw },
 	{}
 };
 MODULE_DEVICE_TABLE(i2c, ub953_id);
diff --git a/drivers/media/i2c/ds90ub960.c b/drivers/media/i2c/ds90ub960.c
index 2cefb3744901..eb391f0259b3 100644
--- a/drivers/media/i2c/ds90ub960.c
+++ b/drivers/media/i2c/ds90ub960.c
@@ -19,7 +19,6 @@
 #include <linux/kthread.h>
 #include <linux/module.h>
 #include <linux/mutex.h>
-#include <linux/of_device.h>
 #include <linux/property.h>
 #include <linux/regmap.h>
 #include <linux/regulator/consumer.h>
@@ -31,6 +30,8 @@
 #include <media/v4l2-event.h>
 #include <media/v4l2-subdev.h>
 
+#define MHZ(v) ((u32)((v) * 1000000U))
+
 #define UB960_POLL_TIME_MS	500
 
 #define UB960_MAX_RX_NPORTS	4
@@ -147,7 +148,13 @@
 #define UB960_XR_SFILTER_CFG_SFILTER_MIN_SHIFT	0
 
 #define UB960_XR_AEQ_CTL1			0x42
-#define UB960_XR_AEQ_CTL1_AEQ_ERR_CTL_SHIFT	4
+#define UB960_XR_AEQ_CTL1_AEQ_ERR_CTL_FPD_CLK	BIT(6)
+#define UB960_XR_AEQ_CTL1_AEQ_ERR_CTL_ENCODING	BIT(5)
+#define UB960_XR_AEQ_CTL1_AEQ_ERR_CTL_PARITY	BIT(4)
+#define UB960_XR_AEQ_CTL1_AEQ_ERR_CTL_MASK        \
+	(UB960_XR_AEQ_CTL1_AEQ_ERR_CTL_FPD_CLK |  \
+	 UB960_XR_AEQ_CTL1_AEQ_ERR_CTL_ENCODING | \
+	 UB960_XR_AEQ_CTL1_AEQ_ERR_CTL_PARITY)
 #define UB960_XR_AEQ_CTL1_AEQ_SFILTER_EN	BIT(0)
 
 #define UB960_XR_AEQ_ERR_THOLD			0x43
@@ -160,9 +167,14 @@
 #define UB960_RR_BCC_STATUS_SLAVE_ERR		BIT(2)
 #define UB960_RR_BCC_STATUS_SLAVE_TO		BIT(1)
 #define UB960_RR_BCC_STATUS_RESP_ERR		BIT(0)
+#define UB960_RR_BCC_STATUS_ERROR_MASK                                    \
+	(UB960_RR_BCC_STATUS_SEQ_ERROR | UB960_RR_BCC_STATUS_MASTER_ERR | \
+	 UB960_RR_BCC_STATUS_MASTER_TO | UB960_RR_BCC_STATUS_SLAVE_ERR |  \
+	 UB960_RR_BCC_STATUS_SLAVE_TO | UB960_RR_BCC_STATUS_RESP_ERR)
 
 #define UB960_RR_FPD3_CAP			0x4A
 #define UB960_RR_RAW_EMBED_DTYPE		0x4B
+#define UB960_RR_RAW_EMBED_DTYPE_LINES_SHIFT	6
 
 #define UB960_SR_FPD3_PORT_SEL			0x4C
 
@@ -173,6 +185,10 @@
 #define UB960_RR_RX_PORT_STS1_PARITY_ERROR	BIT(2)
 #define UB960_RR_RX_PORT_STS1_PORT_PASS		BIT(1)
 #define UB960_RR_RX_PORT_STS1_LOCK_STS		BIT(0)
+#define UB960_RR_RX_PORT_STS1_ERROR_MASK       \
+	(UB960_RR_RX_PORT_STS1_BCC_CRC_ERROR | \
+	 UB960_RR_RX_PORT_STS1_BCC_SEQ_ERROR | \
+	 UB960_RR_RX_PORT_STS1_PARITY_ERROR)
 
 #define UB960_RR_RX_PORT_STS2			0x4E
 #define UB960_RR_RX_PORT_STS2_LINE_LEN_UNSTABLE	BIT(7)
@@ -183,6 +199,8 @@
 #define UB960_RR_RX_PORT_STS2_FREQ_STABLE	BIT(2)
 #define UB960_RR_RX_PORT_STS2_CABLE_FAULT	BIT(1)
 #define UB960_RR_RX_PORT_STS2_LINE_CNT_CHG	BIT(0)
+#define UB960_RR_RX_PORT_STS2_ERROR_MASK       \
+	UB960_RR_RX_PORT_STS2_BUFFER_ERROR
 
 #define UB960_RR_RX_FREQ_HIGH			0x4F
 #define UB960_RR_RX_FREQ_LOW			0x50
@@ -196,6 +214,7 @@
 
 #define UB960_RR_BCC_CONFIG			0x58
 #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
@@ -207,10 +226,17 @@
 #define UB960_RR_SLAVE_ALIAS(n)			(0x65 + (n))
 
 #define UB960_RR_PORT_CONFIG			0x6D
+#define UB960_RR_PORT_CONFIG_FPD3_MODE_MASK	GENMASK(1, 0)
+
 #define UB960_RR_BC_GPIO_CTL(n)			(0x6E + (n)) /* n < 2 */
 #define UB960_RR_RAW10_ID			0x70
+#define UB960_RR_RAW10_ID_VC_SHIFT		6
+#define UB960_RR_RAW10_ID_DT_SHIFT		0
+
 #define UB960_RR_RAW12_ID			0x71
 #define UB960_RR_CSI_VC_MAP			0x72
+#define UB960_RR_CSI_VC_MAP_SHIFT(x)		((x) * 2)
+
 #define UB960_RR_LINE_COUNT_HI			0x73
 #define UB960_RR_LINE_COUNT_LO			0x74
 #define UB960_RR_LINE_LEN_1			0x75
@@ -224,9 +250,15 @@
 #define UB960_RR_CSI_RX_STS_CKSUM_ERR		BIT(2)
 #define UB960_RR_CSI_RX_STS_ECC2_ERR		BIT(1)
 #define UB960_RR_CSI_RX_STS_ECC1_ERR		BIT(0)
+#define UB960_RR_CSI_RX_STS_ERROR_MASK                                    \
+	(UB960_RR_CSI_RX_STS_LENGTH_ERR | UB960_RR_CSI_RX_STS_CKSUM_ERR | \
+	 UB960_RR_CSI_RX_STS_ECC2_ERR | UB960_RR_CSI_RX_STS_ECC1_ERR)
 
 #define UB960_RR_CSI_ERR_COUNTER		0x7B
 #define UB960_RR_PORT_CONFIG2			0x7C
+#define UB960_RR_PORT_CONFIG2_RAW10_8BIT_CTL_MASK GENMASK(7, 6)
+#define UB960_RR_PORT_CONFIG2_RAW10_8BIT_CTL_SHIFT 6
+
 #define UB960_RR_PORT_CONFIG2_LV_POL_LOW	BIT(1)
 #define UB960_RR_PORT_CONFIG2_FV_POL_LOW	BIT(0)
 
@@ -267,6 +299,8 @@
 #define UB960_RR_AEQ_CTL2_SET_AEQ_FLOOR		BIT(2)
 
 #define UB960_RR_AEQ_STATUS			0xD3
+#define UB960_RR_AEQ_STATUS_STATUS_2		GENMASK(5, 3)
+#define UB960_RR_AEQ_STATUS_STATUS_1		GENMASK(2, 0)
 
 #define UB960_RR_AEQ_BYPASS			0xD4
 #define UB960_RR_AEQ_BYPASS_EQ_STAGE1_VALUE_SHIFT	5
@@ -336,8 +370,10 @@
 #define UB960_MIN_AEQ_STROBE_POS -7
 #define UB960_MAX_AEQ_STROBE_POS 7
 
-#define UB960_MIN_MANUAL_STROBE_POS -(7 + 6)
-#define UB960_MAX_MANUAL_STROBE_POS (7 + 6)
+#define UB960_MANUAL_STROBE_EXTRA_DELAY 6
+
+#define UB960_MIN_MANUAL_STROBE_POS -(7 + UB960_MANUAL_STROBE_EXTRA_DELAY)
+#define UB960_MAX_MANUAL_STROBE_POS (7 + UB960_MANUAL_STROBE_EXTRA_DELAY)
 #define UB960_NUM_MANUAL_STROBE_POS (UB960_MAX_MANUAL_STROBE_POS - UB960_MIN_MANUAL_STROBE_POS + 1)
 
 #define UB960_MIN_EQ_LEVEL 0
@@ -584,12 +620,15 @@ static int ub960_read(struct ub960_data *priv, u8 reg, u8 *val)
 	mutex_lock(&priv->reg_lock);
 
 	ret = regmap_read(priv->regmap, reg, &v);
-	if (ret)
+	if (ret) {
 		dev_err(dev, "%s: cannot read register 0x%02x (%d)!\n",
 			__func__, reg, ret);
-	else
-		*val = v;
+		goto out_unlock;
+	}
+
+	*val = v;
 
+out_unlock:
 	mutex_unlock(&priv->reg_lock);
 
 	return ret;
@@ -639,7 +678,7 @@ static int _ub960_rxport_select(struct ub960_data *priv, u8 nport)
 		return 0;
 
 	ret = regmap_write(priv->regmap, UB960_SR_FPD3_PORT_SEL,
-			   (nport << 4) | (1 << nport));
+			   (nport << 4) | BIT(nport));
 	if (ret) {
 		dev_err(dev, "%s: cannot select rxport %d (%d)!\n", __func__,
 			nport, ret);
@@ -663,12 +702,15 @@ static int ub960_rxport_read(struct ub960_data *priv, u8 nport, u8 reg, u8 *val)
 	_ub960_rxport_select(priv, nport);
 
 	ret = regmap_read(priv->regmap, reg, &v);
-	if (ret)
+	if (ret) {
 		dev_err(dev, "%s: cannot read register 0x%02x (%d)!\n",
 			__func__, reg, ret);
-	else
-		*val = v;
+		goto out_unlock;
+	}
+
+	*val = v;
 
+out_unlock:
 	mutex_unlock(&priv->reg_lock);
 
 	return ret;
@@ -704,7 +746,6 @@ static int ub960_rxport_update_bits(struct ub960_data *priv, u8 nport, u8 reg,
 	_ub960_rxport_select(priv, nport);
 
 	ret = regmap_update_bits(priv->regmap, reg, mask, val);
-
 	if (ret)
 		dev_err(dev, "%s: cannot update register 0x%02x (%d)!\n",
 			__func__, reg, ret);
@@ -724,7 +765,7 @@ static int _ub960_csiport_select(struct ub960_data *priv, u8 nport)
 		return 0;
 
 	ret = regmap_write(priv->regmap, UB960_SR_CSI_PORT_SEL,
-			   (nport << 4) | (1 << nport));
+			   (nport << 4) | BIT(nport));
 	if (ret) {
 		dev_err(dev, "%s: cannot select csi port %d (%d)!\n", __func__,
 			nport, ret);
@@ -749,12 +790,15 @@ static int ub960_csiport_read(struct ub960_data *priv, u8 nport, u8 reg,
 	_ub960_csiport_select(priv, nport);
 
 	ret = regmap_read(priv->regmap, reg, &v);
-	if (ret)
+	if (ret) {
 		dev_err(dev, "%s: cannot read register 0x%02x (%d)!\n",
 			__func__, reg, ret);
-	else
-		*val = v;
+		goto out_unlock;
+	}
+
+	*val = v;
 
+out_unlock:
 	mutex_unlock(&priv->reg_lock);
 
 	return ret;
@@ -791,7 +835,6 @@ static int ub960_csiport_update_bits(struct ub960_data *priv, u8 nport, u8 reg,
 	_ub960_csiport_select(priv, nport);
 
 	ret = regmap_update_bits(priv->regmap, reg, mask, val);
-
 	if (ret)
 		dev_err(dev, "%s: cannot update register 0x%02x (%d)!\n",
 			__func__, reg, ret);
@@ -830,14 +873,14 @@ static int ub960_read_ind(struct ub960_data *priv, u8 block, u8 reg, u8 *val)
 
 	ret = _ub960_select_ind_reg_block(priv, block);
 	if (ret)
-		goto out;
+		goto out_unlock;
 
 	ret = regmap_write(priv->regmap, UB960_SR_IND_ACC_ADDR, reg);
 	if (ret) {
 		dev_err(&priv->client->dev,
 			"Write to IND_ACC_ADDR failed when reading %u:%x02x: %d\n",
 			block, reg, ret);
-		goto out;
+		goto out_unlock;
 	}
 
 	ret = regmap_read(priv->regmap, UB960_SR_IND_ACC_DATA, &v);
@@ -845,12 +888,12 @@ static int ub960_read_ind(struct ub960_data *priv, u8 block, u8 reg, u8 *val)
 		dev_err(&priv->client->dev,
 			"Write to IND_ACC_DATA failed when reading %u:%x02x: %d\n",
 			block, reg, ret);
-		goto out;
+		goto out_unlock;
 	}
 
 	*val = v;
 
-out:
+out_unlock:
 	mutex_unlock(&priv->reg_lock);
 
 	return ret;
@@ -863,24 +906,26 @@ static int ub960_write_ind(struct ub960_data *priv, u8 block, u8 reg, u8 val)
 	mutex_lock(&priv->reg_lock);
 
 	ret = _ub960_select_ind_reg_block(priv, block);
+	if (ret)
+		goto out_unlock;
+
+	ret = regmap_write(priv->regmap, UB960_SR_IND_ACC_ADDR, reg);
 	if (ret) {
 		dev_err(&priv->client->dev,
 			"Write to IND_ACC_ADDR failed when writing %u:%x02x: %d\n",
 			block, reg, ret);
-		goto out;
+		goto out_unlock;
 	}
 
-	ret = regmap_write(priv->regmap, UB960_SR_IND_ACC_ADDR, reg);
+	ret = regmap_write(priv->regmap, UB960_SR_IND_ACC_DATA, val);
 	if (ret) {
 		dev_err(&priv->client->dev,
 			"Write to IND_ACC_DATA failed when writing %u:%x02x\n: %d\n",
 			block, reg, ret);
-		goto out;
+		goto out_unlock;
 	}
 
-	ret = regmap_write(priv->regmap, UB960_SR_IND_ACC_DATA, val);
-
-out:
+out_unlock:
 	mutex_unlock(&priv->reg_lock);
 
 	return ret;
@@ -894,25 +939,25 @@ static int ub960_write_ind16(struct ub960_data *priv, u8 block, u8 reg, u16 val)
 
 	ret = _ub960_select_ind_reg_block(priv, block);
 	if (ret)
-		goto out;
+		goto out_unlock;
 
 	ret = regmap_write(priv->regmap, UB960_SR_IND_ACC_ADDR, reg);
 	if (ret)
-		goto out;
+		goto out_unlock;
 
 	ret = regmap_write(priv->regmap, UB960_SR_IND_ACC_DATA, val >> 8);
 	if (ret)
-		goto out;
+		goto out_unlock;
 
 	ret = regmap_write(priv->regmap, UB960_SR_IND_ACC_ADDR, reg + 1);
 	if (ret)
-		goto out;
+		goto out_unlock;
 
 	ret = regmap_write(priv->regmap, UB960_SR_IND_ACC_DATA, val & 0xff);
 	if (ret)
-		goto out;
+		goto out_unlock;
 
-out:
+out_unlock:
 	mutex_unlock(&priv->reg_lock);
 
 	return ret;
@@ -922,28 +967,31 @@ static int ub960_ind_update_bits(struct ub960_data *priv, u8 block, u8 reg,
 				 u8 mask, u8 val)
 {
 	int ret;
-	u32 v;
 
 	mutex_lock(&priv->reg_lock);
 
 	ret = _ub960_select_ind_reg_block(priv, block);
 	if (ret)
-		goto out;
+		goto out_unlock;
 
 	ret = regmap_write(priv->regmap, UB960_SR_IND_ACC_ADDR, reg);
-	if (ret)
-		goto out;
-
-	ret = regmap_read(priv->regmap, UB960_SR_IND_ACC_DATA, &v);
-	if (ret)
-		goto out;
-
-	v &= ~mask;
-	v |= val;
+	if (ret) {
+		dev_err(&priv->client->dev,
+			"Write to IND_ACC_ADDR failed when updating %u:%x02x: %d\n",
+			block, reg, ret);
+		goto out_unlock;
+	}
 
-	ret = regmap_write(priv->regmap, UB960_SR_IND_ACC_DATA, v);
+	ret = regmap_update_bits(priv->regmap, UB960_SR_IND_ACC_DATA, mask,
+				 val);
+	if (ret) {
+		dev_err(&priv->client->dev,
+			"Write to IND_ACC_DATA failed when updating %u:%x02x: %d\n",
+			block, reg, ret);
+		goto out_unlock;
+	}
 
-out:
+out_unlock:
 	mutex_unlock(&priv->reg_lock);
 
 	return ret;
@@ -992,13 +1040,13 @@ static int ub960_atr_attach_client(struct i2c_atr *atr, u32 chan_id,
 	if (!entry) {
 		dev_err(dev, "rx%u: alias pool exhausted\n", rxport->nport);
 		ret = -EADDRNOTAVAIL;
-		goto out;
+		goto out_unlock;
 	}
 
-	if (port_reg_idx_mask == (1 << UB960_MAX_PORT_ALIASES) - 1) {
+	if (port_reg_idx_mask == GENMASK(UB960_MAX_PORT_ALIASES - 1, 0)) {
 		dev_err(dev, "rx%u: all aliases in use\n", rxport->nport);
 		ret = -EADDRNOTAVAIL;
-		goto out;
+		goto out_unlock;
 	}
 
 	alias = entry->alias_id;
@@ -1022,7 +1070,7 @@ static int ub960_atr_attach_client(struct i2c_atr *atr, u32 chan_id,
 	dev_dbg(dev, "rx%u: client 0x%02x mapped at alias 0x%02x (%s)\n",
 		rxport->nport, client->addr, alias, client->name);
 
-out:
+out_unlock:
 	mutex_unlock(&priv->atr_alias_table.lock);
 	return ret;
 }
@@ -1055,7 +1103,7 @@ static void ub960_atr_detach_client(struct i2c_atr *atr, u32 chan_id,
 	if (pool_idx == priv->atr_alias_table.num_entries) {
 		dev_err(dev, "rx%u: client 0x%02x is not mapped!\n",
 			rxport->nport, client->addr);
-		goto out;
+		goto out_unlock;
 	}
 
 	alias = entry->alias_id;
@@ -1071,7 +1119,7 @@ static void ub960_atr_detach_client(struct i2c_atr *atr, u32 chan_id,
 	dev_dbg(dev, "rx%u: client 0x%02x unmapped from alias 0x%02x (%s)\n",
 		rxport->nport, client->addr, alias, client->name);
 
-out:
+out_unlock:
 	mutex_unlock(&priv->atr_alias_table.lock);
 }
 
@@ -1103,7 +1151,7 @@ static int ub960_parse_dt_txport(struct ub960_data *priv,
 	priv->txports[nport] = txport;
 
 	ret = fwnode_property_count_u32(ep_fwnode, "data-lanes");
-	if (ret <= 0) {
+	if (ret < 0) {
 		dev_err(dev, "tx%u: failed to parse 'data-lanes': %d\n", nport,
 			ret);
 		goto err_free_txport;
@@ -1111,20 +1159,6 @@ static int ub960_parse_dt_txport(struct ub960_data *priv,
 
 	txport->num_data_lanes = ret;
 
-	ret = fwnode_property_count_u64(ep_fwnode, "link-frequencies");
-	if (ret < 0) {
-		dev_err(dev, "tx%u: failed to parse 'link-frequencies': %d\n",
-			nport, ret);
-		goto err_free_txport;
-	}
-
-	if (ret != 1) {
-		dev_err(dev,
-			"tx%u: 'link-frequencies' must contain a single frequency: %d\n",
-			nport, ret);
-		goto err_free_txport;
-	}
-
 	ret = fwnode_property_read_u64(ep_fwnode, "link-frequencies", &freq);
 	if (ret) {
 		dev_err(dev, "tx%u: failed to read 'link-frequencies': %d\n",
@@ -1135,10 +1169,10 @@ static int ub960_parse_dt_txport(struct ub960_data *priv,
 	priv->tx_link_freq[0] = freq;
 	priv->tx_data_rate = freq * 2;
 
-	if (priv->tx_data_rate != 1600000000 &&
-	    priv->tx_data_rate != 1200000000 &&
-	    priv->tx_data_rate != 800000000 &&
-	    priv->tx_data_rate != 400000000) {
+	if (priv->tx_data_rate != MHZ(1600) &&
+	    priv->tx_data_rate != MHZ(1200) &&
+	    priv->tx_data_rate != MHZ(800) &&
+	    priv->tx_data_rate != MHZ(400)) {
 		dev_err(dev, "tx%u: invalid 'link-frequencies' value\n", nport);
 		return -EINVAL;
 	}
@@ -1160,14 +1194,14 @@ static void ub960_csi_handle_events(struct ub960_data *priv, u8 nport)
 	int ret;
 
 	ret = ub960_csiport_read(priv, nport, UB960_TR_CSI_TX_ISR, &csi_tx_isr);
+	if (ret)
+		return;
 
-	if (!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_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);
-	}
+	if (csi_tx_isr & UB960_TR_CSI_TX_ISR_IS_CSI_PASS_ERROR)
+		dev_warn(dev, "TX%u: CSI_PASS_ERROR\n", nport);
 }
 
 /* -----------------------------------------------------------------------------
@@ -1193,8 +1227,8 @@ static int ub960_rxport_enable_vpocs(struct ub960_data *priv)
 	return 0;
 
 err_disable_vpocs:
-	for (; nport > 0; --nport) {
-		struct ub960_rxport *rxport = priv->rxports[nport - 1];
+	while (nport--) {
+		struct ub960_rxport *rxport = priv->rxports[nport];
 
 		if (!rxport || !rxport->vpoc)
 			continue;
@@ -1253,12 +1287,16 @@ static int ub960_rxport_get_strobe_pos(struct ub960_data *priv,
 	ub960_read_ind(priv, UB960_IND_TARGET_RX_ANA(nport),
 		       UB960_IR_RX_ANA_STROBE_SET_CLK, &v);
 
-	clk_delay = v & UB960_IR_RX_ANA_STROBE_SET_CLK_NO_EXTRA_DELAY ? 0 : 6;
+	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);
 
-	data_delay = v & UB960_IR_RX_ANA_STROBE_SET_DATA_NO_EXTRA_DELAY ? 0 : 6;
+	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);
 	if (ret)
@@ -1282,17 +1320,13 @@ static void ub960_rxport_set_strobe_pos(struct ub960_data *priv,
 {
 	u8 clk_delay, data_delay;
 
-	if (WARN_ON(strobe_pos < UB960_MIN_MANUAL_STROBE_POS ||
-		    strobe_pos > UB960_MAX_MANUAL_STROBE_POS))
-		return;
-
 	clk_delay = UB960_IR_RX_ANA_STROBE_SET_CLK_NO_EXTRA_DELAY;
 	data_delay = UB960_IR_RX_ANA_STROBE_SET_DATA_NO_EXTRA_DELAY;
 
-	if (strobe_pos < -7)
-		clk_delay = abs(strobe_pos) - 6;
-	else if (strobe_pos > 7)
-		data_delay = strobe_pos - 6;
+	if (strobe_pos < UB960_MIN_AEQ_STROBE_POS)
+		clk_delay = abs(strobe_pos) - UB960_MANUAL_STROBE_EXTRA_DELAY;
+	else if (strobe_pos > UB960_MAX_AEQ_STROBE_POS)
+		data_delay = strobe_pos - UB960_MANUAL_STROBE_EXTRA_DELAY;
 	else if (strobe_pos < 0)
 		clk_delay = abs(strobe_pos) | UB960_IR_RX_ANA_STROBE_SET_CLK_NO_EXTRA_DELAY;
 	else if (strobe_pos > 0)
@@ -1308,11 +1342,9 @@ static void ub960_rxport_set_strobe_pos(struct ub960_data *priv,
 static void ub960_rxport_set_strobe_range(struct ub960_data *priv,
 					  s8 strobe_min, s8 strobe_max)
 {
-	WARN_ON(strobe_min < UB960_MIN_AEQ_STROBE_POS);
-	WARN_ON(strobe_max > UB960_MAX_AEQ_STROBE_POS);
-
-	strobe_min += 7;
-	strobe_max += 7;
+	/* 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) |
@@ -1329,7 +1361,8 @@ static int ub960_rxport_get_eq_level(struct ub960_data *priv,
 	if (ret)
 		return ret;
 
-	*eq_level = (v & 0x7) + ((v >> 3) & 0x7);
+	*eq_level = (v & UB960_RR_AEQ_STATUS_STATUS_1) +
+		    (v & UB960_RR_AEQ_STATUS_STATUS_2);
 
 	return 0;
 }
@@ -1338,26 +1371,24 @@ static void 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;
 	u8 v;
 
-	if (eq_level <= 7) {
+	if (eq_level <= eq_stage_max) {
 		eq_stage_1_select_value = eq_level;
 		eq_stage_2_select_value = 0;
 	} else {
-		eq_stage_1_select_value = 7;
-		eq_stage_2_select_value = eq_level - 7;
+		eq_stage_1_select_value = eq_stage_max;
+		eq_stage_2_select_value = eq_level - eq_stage_max;
 	}
 
-	WARN_ON(eq_stage_1_select_value > 7);
-	WARN_ON(eq_stage_2_select_value > 7);
-
 	ub960_rxport_read(priv, nport, UB960_RR_AEQ_BYPASS, &v);
 
 	v &= ~(UB960_RR_AEQ_BYPASS_EQ_STAGE1_VALUE_MASK |
 	       UB960_RR_AEQ_BYPASS_EQ_STAGE2_VALUE_MASK);
 	v |= eq_stage_1_select_value << UB960_RR_AEQ_BYPASS_EQ_STAGE1_VALUE_SHIFT;
 	v |= eq_stage_2_select_value << UB960_RR_AEQ_BYPASS_EQ_STAGE2_VALUE_SHIFT;
-	v |= UB960_RR_AEQ_BYPASS_ENABLE; /* Enable AEQ Bypass */
+	v |= UB960_RR_AEQ_BYPASS_ENABLE;
 
 	ub960_rxport_write(priv, nport, UB960_RR_AEQ_BYPASS, v);
 }
@@ -1388,7 +1419,7 @@ static void ub960_rxport_config_eq(struct ub960_data *priv, unsigned int nport)
 	} else {
 		/* Enable SFILTER and error control */
 		ub960_write(priv, UB960_XR_AEQ_CTL1,
-			    (0x7 << UB960_XR_AEQ_CTL1_AEQ_ERR_CTL_SHIFT) |
+			    UB960_XR_AEQ_CTL1_AEQ_ERR_CTL_MASK |
 				    UB960_XR_AEQ_CTL1_AEQ_SFILTER_EN);
 
 		/* Set AEQ strobe range */
@@ -1472,8 +1503,10 @@ static int ub960_rxport_link_ok(struct ub960_data *priv, unsigned int nport,
 
 	parity_errors = (v1 << 8) | v2;
 
-	errors = (rx_port_sts1 & 0x2c) || (rx_port_sts2 & 0x20) ||
-		 (bcc_sts & 0x3f) || (csi_rx_sts & 0xf) || csi_err_cnt ||
+	errors = (rx_port_sts1 & UB960_RR_RX_PORT_STS1_ERROR_MASK) ||
+		 (rx_port_sts2 & UB960_RR_RX_PORT_STS2_ERROR_MASK) ||
+		 (bcc_sts & UB960_RR_BCC_STATUS_ERROR_MASK) ||
+		 (csi_rx_sts & UB960_RR_CSI_RX_STS_ERROR_MASK) || csi_err_cnt ||
 		 parity_errors;
 
 	*ok = !errors;
@@ -1621,7 +1654,6 @@ static unsigned long ub960_calc_bc_clk_rate_ub960(struct ub960_data *priv,
 		break;
 
 	default:
-		WARN_ON(true);
 		return 0;
 	}
 
@@ -1644,7 +1676,6 @@ static unsigned long ub960_calc_bc_clk_rate_ub9702(struct ub960_data *priv,
 		return 9437500;
 
 	default:
-		WARN_ON(true);
 		return 0;
 	}
 }
@@ -1716,17 +1747,17 @@ static int ub960_rxport_add_serializers(struct ub960_data *priv)
 	return 0;
 
 err_remove_sers:
-	for (; nport > 0; --nport) {
-		struct ub960_rxport *rxport = priv->rxports[nport - 1];
+	while (nport--) {
+		struct ub960_rxport *rxport = priv->rxports[nport];
 
 		if (!rxport)
 			continue;
 
-		rxport = priv->rxports[nport - 1];
+		rxport = priv->rxports[nport];
 		if (!rxport)
 			continue;
 
-		ub960_rxport_remove_serializer(priv, nport - 1);
+		ub960_rxport_remove_serializer(priv, nport);
 	}
 
 	return ret;
@@ -1756,7 +1787,7 @@ static void ub960_init_tx_port(struct ub960_data *priv,
 	 * From the datasheet: "initial CSI Skew-Calibration
 	 * sequence [...] should be set when operating at 1.6 Gbps"
 	 */
-	if (priv->tx_data_rate == 1600000000)
+	if (priv->tx_data_rate == MHZ(1600))
 		csi_ctl |= UB960_TR_CSI_CTL_CSI_CAL_EN;
 
 	csi_ctl |= (4 - txport->num_data_lanes) << 4;
@@ -1773,19 +1804,19 @@ static int ub960_init_tx_ports(struct ub960_data *priv)
 	/* TX ports */
 
 	switch (priv->tx_data_rate) {
-	case 1600000000:
+	case MHZ(1600):
 	default:
 		speed_select = 0;
 		pll_div = 0x10;
 		break;
-	case 1200000000:
+	case MHZ(1200):
 		speed_select = 1;
 		break;
-	case 800000000:
+	case MHZ(800):
 		speed_select = 2;
 		pll_div = 0x10;
 		break;
-	case 400000000:
+	case MHZ(400):
 		speed_select = 3;
 		pll_div = 0x10;
 		break;
@@ -1797,17 +1828,17 @@ static int ub960_init_tx_ports(struct ub960_data *priv)
 		ub960_write(priv, UB960_SR_CSI_PLL_DIV, pll_div);
 
 		switch (priv->tx_data_rate) {
-		case 1600000000:
+		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);
 			break;
-		case 800000000:
+		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);
 			break;
-		case 400000000:
+		case MHZ(400):
 			ub960_write_ind(priv, UB960_IND_TARGET_CSI_ANA, 0x92, 0xA0);
 			break;
 		}
@@ -1858,32 +1889,34 @@ static void ub960_init_rx_port_ub960(struct ub960_data *priv,
 		break;
 
 	default:
-		WARN_ON(true);
 		return;
 	}
 
-	ub960_rxport_update_bits(priv, nport, UB960_RR_BCC_CONFIG, 0x7,
+	ub960_rxport_update_bits(priv, nport, UB960_RR_BCC_CONFIG,
+				 UB960_RR_BCC_CONFIG_BC_FREQ_SEL_MASK,
 				 bc_freq_val);
 
 	switch (rxport->rx_mode) {
-	default:
-		WARN_ON(true);
-		fallthrough;
-
 	case RXPORT_MODE_RAW10:
 		/* FPD3_MODE = RAW10 Mode (DS90UB913A-Q1 / DS90UB933-Q1 compatible) */
-		ub960_rxport_update_bits(priv, nport, UB960_RR_PORT_CONFIG, 0x3,
+		ub960_rxport_update_bits(priv, nport, UB960_RR_PORT_CONFIG,
+					 UB960_RR_PORT_CONFIG_FPD3_MODE_MASK,
 					 0x3);
 
 		/*
-		 * RAW10_8BIT_CTL = 0b11 : 8-bit processing using lower 8 bits
-		 * 0b10 : 8-bit processing using upper 8 bits
+		 * RAW10_8BIT_CTL = 0b10 : 8-bit processing using upper 8 bits
 		 */
 		ub960_rxport_update_bits(priv, nport, UB960_RR_PORT_CONFIG2,
-					 0x3 << 6, 0x2 << 6);
+			UB960_RR_PORT_CONFIG2_RAW10_8BIT_CTL_MASK,
+			0x2 << UB960_RR_PORT_CONFIG2_RAW10_8BIT_CTL_SHIFT);
 
 		break;
 
+	case RXPORT_MODE_RAW12_HF:
+	case RXPORT_MODE_RAW12_LF:
+		/* Not implemented */
+		return;
+
 	case RXPORT_MODE_CSI2_SYNC:
 	case RXPORT_MODE_CSI2_ASYNC:
 		/* CSI-2 Mode (DS90UB953-Q1 compatible) */
@@ -1951,7 +1984,6 @@ static void ub960_init_rx_port_ub9702_fpd3(struct ub960_data *priv,
 		break;
 
 	default:
-		WARN_ON(true);
 		return;
 	}
 
@@ -1980,7 +2012,7 @@ static void ub960_init_rx_port_ub9702_fpd3(struct ub960_data *priv,
 
 	/* RX port to half-rate */
 	ub960_update_bits(priv, UB960_SR_FPD_RATE_CFG, 0x3 << (nport * 2),
-			  1 << (nport * 2));
+			  BIT(nport * 2));
 }
 
 static void ub960_init_rx_port_ub9702_fpd4_aeq(struct ub960_data *priv,
@@ -2045,7 +2077,6 @@ static void ub960_init_rx_port_ub9702_fpd4(struct ub960_data *priv,
 		break;
 
 	default:
-		WARN_ON(true);
 		return;
 	}
 
@@ -2091,10 +2122,6 @@ static void ub960_init_rx_port_ub9702(struct ub960_data *priv,
 		ub960_init_rx_port_ub9702_fpd4(priv, rxport);
 
 	switch (rxport->rx_mode) {
-	default:
-		WARN_ON(true);
-		fallthrough;
-
 	case RXPORT_MODE_RAW10:
 		/*
 		 * RAW10_8BIT_CTL = 0b11 : 8-bit processing using lower 8 bits
@@ -2105,6 +2132,11 @@ static void ub960_init_rx_port_ub9702(struct ub960_data *priv,
 
 		break;
 
+	case RXPORT_MODE_RAW12_HF:
+	case RXPORT_MODE_RAW12_LF:
+		/* Not implemented */
+		return;
+
 	case RXPORT_MODE_CSI2_SYNC:
 	case RXPORT_MODE_CSI2_ASYNC:
 
@@ -2283,7 +2315,7 @@ static void ub960_get_vc_maps(struct ub960_data *priv,
 			      struct v4l2_subdev_state *state, u8 *vc)
 {
 	const struct v4l2_subdev_krouting *routing = &state->routing;
-	u8 cur_vc[UB960_MAX_TX_NPORTS] = { 0 };
+	u8 cur_vc[UB960_MAX_TX_NPORTS] = { };
 	u8 handled_mask = 0;
 	unsigned int i;
 
@@ -2292,7 +2324,6 @@ static void ub960_get_vc_maps(struct ub960_data *priv,
 		unsigned int rx, tx;
 
 		rx = ub960_pad_to_port(priv, route->sink_pad);
-
 		if (BIT(rx) & handled_mask)
 			continue;
 
@@ -2360,8 +2391,8 @@ static int ub960_configure_ports_for_streaming(struct ub960_data *priv,
 		u8 meta_dt;
 		u32 meta_lines;
 		u32 tx_port;
-	} rx_data[UB960_MAX_RX_NPORTS] = { 0 };
-	u8 vc_map[UB960_MAX_RX_NPORTS] = { 0 };
+	} rx_data[UB960_MAX_RX_NPORTS] = { };
+	u8 vc_map[UB960_MAX_RX_NPORTS] = { };
 
 	ub960_get_vc_maps(priv, state, vc_map);
 
@@ -2432,19 +2463,20 @@ static int ub960_configure_ports_for_streaming(struct ub960_data *priv,
 			continue;
 
 		switch (rxport->rx_mode) {
-		default:
-			WARN_ON(true);
-			fallthrough;
-
 		case RXPORT_MODE_RAW10:
 			ub960_rxport_write(priv, nport, UB960_RR_RAW10_ID,
-					   rx_data[nport].pixel_dt | (vc << 6));
+				rx_data[nport].pixel_dt | (vc << UB960_RR_RAW10_ID_VC_SHIFT));
 
 			ub960_rxport_write(priv, rxport->nport,
-					   UB960_RR_RAW_EMBED_DTYPE,
-					   (rx_data[nport].meta_lines << 6) |
-						   rx_data[nport].meta_dt);
+				UB960_RR_RAW_EMBED_DTYPE,
+				(rx_data[nport].meta_lines << UB960_RR_RAW_EMBED_DTYPE_LINES_SHIFT) |
+					rx_data[nport].meta_dt);
+
+			break;
 
+		case RXPORT_MODE_RAW12_HF:
+		case RXPORT_MODE_RAW12_LF:
+			/* Not implemented */
 			break;
 
 		case RXPORT_MODE_CSI2_SYNC:
@@ -2452,8 +2484,10 @@ static int ub960_configure_ports_for_streaming(struct ub960_data *priv,
 			if (!priv->hw_data->is_ub9702) {
 				/* Map all VCs from this port to the same VC */
 				ub960_rxport_write(priv, nport, UB960_RR_CSI_VC_MAP,
-						   (vc << 6) | (vc << 4) |
-							   (vc << 2) | (vc << 0));
+						   (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)));
 			} else {
 				unsigned int i;
 
@@ -2485,16 +2519,13 @@ static int ub960_configure_ports_for_streaming(struct ub960_data *priv,
 static void ub960_update_streaming_status(struct ub960_data *priv)
 {
 	unsigned int i;
-	bool streaming = false;
 
 	for (i = 0; i < UB960_MAX_NPORTS; ++i) {
-		if (priv->stream_enable_mask[i]) {
-			streaming = true;
+		if (priv->stream_enable_mask[i])
 			break;
-		}
 	}
 
-	priv->streaming = streaming;
+	priv->streaming = i < UB960_MAX_NPORTS;
 }
 
 static int ub960_enable_streams(struct v4l2_subdev *sd,
@@ -2506,7 +2537,7 @@ static int ub960_enable_streams(struct v4l2_subdev *sd,
 	const struct v4l2_subdev_krouting *routing;
 	unsigned int source_stream;
 	int ret;
-	u64 sink_streams[UB960_MAX_RX_NPORTS] = { 0 };
+	u64 sink_streams[UB960_MAX_RX_NPORTS] = { };
 	unsigned int nport;
 	unsigned int failed_port;
 
@@ -2607,7 +2638,8 @@ static int ub960_enable_streams(struct v4l2_subdev *sd,
 			priv->rxports[nport]->source_sd,
 			priv->rxports[nport]->source_sd_pad,
 			sink_streams[nport]);
-		WARN_ON(ret);
+		if (ret)
+			dev_err(dev, "Failed to disable streams: %d\n", ret);
 
 		priv->stream_enable_mask[nport] &= ~sink_streams[nport];
 
@@ -2636,7 +2668,7 @@ static int ub960_disable_streams(struct v4l2_subdev *sd,
 	const struct v4l2_subdev_krouting *routing;
 	int ret;
 	unsigned int source_stream;
-	u64 sink_streams[UB960_MAX_RX_NPORTS] = { 0 };
+	u64 sink_streams[UB960_MAX_RX_NPORTS] = { };
 	unsigned int nport;
 
 	dev_dbg(dev, "Disable streams %u:%#llx\n", source_pad,
@@ -2681,7 +2713,8 @@ static int ub960_disable_streams(struct v4l2_subdev *sd,
 			priv->rxports[nport]->source_sd,
 			priv->rxports[nport]->source_sd_pad,
 			sink_streams[nport]);
-		WARN_ON(ret);
+		if (ret)
+			dev_err(dev, "Failed to disable streams: %d\n", ret);
 
 		priv->stream_enable_mask[nport] &= ~sink_streams[nport];
 
@@ -2709,7 +2742,7 @@ static int ub960_s_stream(struct v4l2_subdev *sd, int enable)
 	const struct v4l2_subdev_krouting *routing;
 	struct v4l2_subdev_state *state;
 	struct v4l2_subdev_route *route;
-	u64 pad_stream_masks[UB960_MAX_TX_NPORTS] = { 0 };
+	u64 pad_stream_masks[UB960_MAX_TX_NPORTS] = { };
 	unsigned int nport;
 	int ret = 0;
 
@@ -2731,15 +2764,15 @@ static int ub960_s_stream(struct v4l2_subdev *sd, int enable)
 				pad_stream_masks[nport]);
 
 			if (ret) {
-				for (; nport > 0; --nport) {
-					if (pad_stream_masks[nport - 1] == 0)
+				while (nport--) {
+					if (pad_stream_masks[nport] == 0)
 						continue;
 
 					ub960_disable_streams(
 						sd, state,
 						priv->hw_data->num_rxports +
-							nport - 1,
-						pad_stream_masks[nport - 1]);
+							nport,
+						pad_stream_masks[nport]);
 				}
 
 				break;
@@ -2827,7 +2860,7 @@ static int ub960_get_frame_desc(struct v4l2_subdev *sd, unsigned int pad,
 	struct v4l2_subdev_state *state;
 	int ret = 0;
 	struct device *dev = &priv->client->dev;
-	u8 vc_map[UB960_MAX_RX_NPORTS] = { 0 };
+	u8 vc_map[UB960_MAX_RX_NPORTS] = { };
 
 	if (!ub960_pad_is_source(priv, pad))
 		return -EINVAL;
@@ -2861,7 +2894,7 @@ static int ub960_get_frame_desc(struct v4l2_subdev *sd, unsigned int pad,
 			dev_err(dev,
 				"Failed to get source frame desc for pad %u\n",
 				route->sink_pad);
-			goto out;
+			goto out_unlock;
 		}
 
 		for (i = 0; i < source_fd.num_entries; ++i)
@@ -2874,7 +2907,7 @@ static int ub960_get_frame_desc(struct v4l2_subdev *sd, unsigned int pad,
 			dev_err(dev,
 				"Failed to find stream from source frame desc\n");
 			ret = -EPIPE;
-			goto out;
+			goto out_unlock;
 		}
 
 		fd->entry[fd->num_entries].stream = route->source_stream;
@@ -2896,14 +2929,14 @@ static int ub960_get_frame_desc(struct v4l2_subdev *sd, unsigned int pad,
 
 			if (!fmt) {
 				ret = -EINVAL;
-				goto out;
+				goto out_unlock;
 			}
 
 			ub960_fmt = ub960_find_format(fmt->code);
 			if (!ub960_fmt) {
 				dev_err(dev, "Unable to find format\n");
 				ret = -EINVAL;
-				goto out;
+				goto out_unlock;
 			}
 
 			fd->entry[fd->num_entries].bus.csi2.dt =
@@ -2913,7 +2946,7 @@ static int ub960_get_frame_desc(struct v4l2_subdev *sd, unsigned int pad,
 		fd->num_entries++;
 	}
 
-out:
+out_unlock:
 	v4l2_subdev_unlock_state(state);
 
 	return ret;
@@ -2995,7 +3028,7 @@ static int ub960_log_status(struct v4l2_subdev *sd)
 	struct v4l2_subdev_state *state;
 	unsigned int nport;
 	u8 v = 0, v1 = 0, v2 = 0;
-	char id[7];
+	u8 id[7];
 
 	state = v4l2_subdev_lock_and_get_active_state(sd);
 
@@ -3275,31 +3308,30 @@ 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;
 
 	ret = ub960_read(priv, UB960_SR_INTERRUPT_STS, &int_sts);
+	if (ret || !int_sts)
+		return IRQ_NONE;
 
-	if (!ret && int_sts) {
-		u8 fwd_sts;
+	dev_dbg(&priv->client->dev, "INTERRUPT_STS %x\n", int_sts);
 
-		dev_dbg(&priv->client->dev, "INTERRUPT_STS %x\n", int_sts);
+	ub960_read(priv, UB960_SR_FWD_STS, &fwd_sts);
 
-		ub960_read(priv, UB960_SR_FWD_STS, &fwd_sts);
+	dev_dbg(&priv->client->dev, "FWD_STS %#02x\n", fwd_sts);
 
-		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);
-		}
+	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);
+	}
 
-		for (i = 0; i < priv->hw_data->num_rxports; i++) {
-			if (!priv->rxports[i])
-				continue;
+	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))
+			ub960_rxport_handle_events(priv, i);
 	}
 
 	return IRQ_HANDLED;
@@ -3469,7 +3501,7 @@ ub960_parse_dt_rxport_link_properties(struct ub960_data *priv,
 		dev_err(dev, "rx%u: illegal 'strobe-pos' value: %d\n", nport,
 			strobe_pos);
 	} else {
-		// NOTE: ignored unless global manual strobe pos is set
+		/* NOTE: ignored unless global manual strobe pos is set */
 		rxport->eq.strobe_pos = strobe_pos;
 		if (!priv->strobe.manual)
 			dev_warn(dev,
@@ -3620,12 +3652,14 @@ ub960_fwnode_get_link_by_regs(struct fwnode_handle *links_fwnode,
 	fwnode_for_each_child_node(links_fwnode, link_fwnode) {
 		u32 link_num;
 
-		if (strncmp(fwnode_get_name(link_fwnode), "link@", 5) != 0)
+		if (!str_has_prefix(fwnode_get_name(link_fwnode), "link@"))
 			continue;
 
 		ret = fwnode_property_read_u32(link_fwnode, "reg", &link_num);
-		if (ret)
+		if (ret) {
+			fwnode_handle_put(link_fwnode);
 			return NULL;
+		}
 
 		if (nport == link_num) {
 			fwnode_handle_put(link_fwnode);
@@ -3823,8 +3857,8 @@ static int ub960_v4l2_notifier_register(struct ub960_data *priv)
 					       rxport->source_ep_fwnode,
 					       struct ub960_asd);
 		if (IS_ERR(asd)) {
-			dev_err(dev, "Failed to add subdev for source %u: %ld",
-				i, PTR_ERR(asd));
+			dev_err(dev, "Failed to add subdev for source %u: %pe",
+				i, asd);
 			v4l2_async_nf_cleanup(&priv->notifier);
 			return PTR_ERR(asd);
 		}
@@ -3857,8 +3891,7 @@ static int ub960_create_subdev(struct ub960_data *priv)
 	int ret;
 
 	v4l2_i2c_subdev_init(&priv->sd, priv->client, &ub960_subdev_ops);
-	v4l2_ctrl_handler_init(&priv->ctrl_handler,
-			       ARRAY_SIZE(ub960_tpg_qmenu) - 1);
+	v4l2_ctrl_handler_init(&priv->ctrl_handler, 1);
 	priv->sd.ctrl_handler = &priv->ctrl_handler;
 
 	v4l2_ctrl_new_std_menu_items(&priv->ctrl_handler, &ub960_ctrl_ops,
@@ -4011,14 +4044,13 @@ static int ub960_enable_core_hw(struct ub960_data *priv)
 	u8 refclk_freq;
 
 	ret = regulator_enable(priv->vddio);
-	if (ret) {
-		dev_err(dev, "failed to enable VDDIO regulator\n");
-		return ret;
-	}
+	if (ret)
+		return dev_err_probe(dev, ret,
+				     "failed to enable VDDIO regulator\n");
 
 	ret = clk_prepare_enable(priv->refclk);
 	if (ret) {
-		dev_err(dev, "Failed to enable refclk: %d\n", ret);
+		dev_err_probe(dev, ret, "Failed to enable refclk\n");
 		goto err_disable_vddio;
 	}
 
@@ -4036,7 +4068,7 @@ static int ub960_enable_core_hw(struct ub960_data *priv)
 	/* Runtime check register accessibility */
 	ret = ub960_read(priv, UB960_SR_REV_MASK, &rev_mask);
 	if (ret) {
-		dev_err(dev, "Cannot read first register (%d), abort\n", ret);
+		dev_err_probe(dev, ret, "Cannot read first register, abort\n");
 		goto err_pd_gpio;
 	}
 
@@ -4061,9 +4093,7 @@ static int ub960_enable_core_hw(struct ub960_data *priv)
 	return 0;
 
 err_pd_gpio:
-	if (priv->pd_gpio)
-		gpiod_set_value_cansleep(priv->pd_gpio, 1);
-
+	gpiod_set_value_cansleep(priv->pd_gpio, 1);
 	clk_disable_unprepare(priv->refclk);
 err_disable_vddio:
 	regulator_disable(priv->vddio);
@@ -4073,11 +4103,8 @@ static int ub960_enable_core_hw(struct ub960_data *priv)
 
 static void ub960_disable_core_hw(struct ub960_data *priv)
 {
-	if (priv->pd_gpio)
-		gpiod_set_value_cansleep(priv->pd_gpio, 1);
-
+	gpiod_set_value_cansleep(priv->pd_gpio, 1);
 	clk_disable_unprepare(priv->refclk);
-
 	regulator_disable(priv->vddio);
 }
 
@@ -4093,9 +4120,7 @@ static int ub960_probe(struct i2c_client *client)
 
 	priv->client = client;
 
-	priv->hw_data = of_device_get_match_data(dev);
-	if (!priv->hw_data)
-		return -ENODEV;
+	priv->hw_data = device_get_match_data(dev);
 
 	mutex_init(&priv->reg_lock);
 	mutex_init(&priv->atr_alias_table.lock);
@@ -4144,7 +4169,7 @@ static int ub960_probe(struct i2c_client *client)
 
 	ub960_reset(priv, false);
 
-	ub960_rxport_wait_locks(priv, 0xf, NULL);
+	ub960_rxport_wait_locks(priv, GENMASK(3, 0), NULL);
 
 	/*
 	 * Clear any errors caused by switching the RX port settings while
@@ -4222,8 +4247,8 @@ static const struct ub960_hw_data ds90ub9702_hw = {
 };
 
 static const struct i2c_device_id ub960_id[] = {
-	{ "ds90ub960-q1", 0 },
-	{ "ds90ub9702-q1", 0 },
+	{ "ds90ub960-q1", (kernel_ulong_t)&ds90ub960_hw },
+	{ "ds90ub9702-q1", (kernel_ulong_t)&ds90ub9702_hw },
 	{}
 };
 MODULE_DEVICE_TABLE(i2c, ub960_id);
@@ -4241,7 +4266,6 @@ static struct i2c_driver ds90ub960_driver = {
 	.id_table	= ub960_id,
 	.driver = {
 		.name	= "ds90ub960",
-		.owner = THIS_MODULE,
 		.of_match_table = ub960_dt_ids,
 	},
 };
diff --git a/include/linux/i2c-atr.h b/include/linux/i2c-atr.h
index 10a313ab2105..721d08a6ff9b 100644
--- a/include/linux/i2c-atr.h
+++ b/include/linux/i2c-atr.h
@@ -20,8 +20,6 @@ struct i2c_atr;
 
 /**
  * struct i2c_atr_ops - Callbacks from ATR to the device driver.
- * @select:        Ask the driver to select a child bus (optional)
- * @deselect:      Ask the driver to deselect a child bus (optional)
  * @attach_client: Notify the driver of a new device connected on a child
  *                 bus. The driver must choose an I2C alias, configure the
  *                 hardware to use it and return it in `alias_id`.
@@ -32,8 +30,6 @@ struct i2c_atr;
  * All these functions return 0 on success, a negative error code otherwise.
  */
 struct i2c_atr_ops {
-	int (*select)(struct i2c_atr *atr, u32 chan_id);
-	int (*deselect)(struct i2c_atr *atr, u32 chan_id);
 	int (*attach_client)(struct i2c_atr *atr, u32 chan_id,
 			     const struct i2c_client *client, u16 *alias_id);
 	void (*detach_client)(struct i2c_atr *atr, u32 chan_id,

base-commit: 76dcd734eca23168cb008912c0f69ff408905235
prerequisite-patch-id: 341bbdcbd14f0b6f38c88f1390f9437873a03430
prerequisite-patch-id: e5d34269150d94ecb7fd670ad31e14aaae78e099
prerequisite-patch-id: 24ff7b1c013fa9acd8b93c2506eae39eb2a1021c
prerequisite-patch-id: 15edf6091d7c2d340f25711961bb8459addc8d58
prerequisite-patch-id: 9beff6fd1d22dbfe565931de81b27739e45ced05
prerequisite-patch-id: 37bc00c7315371c9a906af0d718ecedd871a43e0
prerequisite-patch-id: 8218595c50635ab48a9c8cd8c580da9f431d539f
prerequisite-patch-id: 7f163276a04d212d009ee6e96fb545d5b781cc44
prerequisite-patch-id: 0db299d92565612520411ef624e097131feb2d97
prerequisite-patch-id: 6b521ad1868b9a507930dd6a2e0e2d19b5947456
prerequisite-patch-id: d32e1105a1285cceac8fd8e84649070174a6b23e
prerequisite-patch-id: 2927a4ef079c55e7807cda150d4b9eb29978136a
prerequisite-patch-id: 77546a2e202557910e9a3635534163cc80134ea4
prerequisite-patch-id: 462fabb2b21019636e1f7e793dafc51caf40400e
prerequisite-patch-id: 604c8c3f3e7fab7698eb73795bae573f88b808db
prerequisite-patch-id: 75a3d7b072e718fb2bd854743b9b2023d68a822b
prerequisite-patch-id: a9c64a3360938ac230261ffc3e0cbd8cb66550d3
prerequisite-patch-id: a5c57341047e53ecaeb28181319700dd3ace62aa
prerequisite-patch-id: e9b8da97c9fea3cd3268adf8387cb3df179649e5
prerequisite-patch-id: 2767b8af9e0742b52b81b2dbce3b5ce5203e3610
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2023-01-25 11:41 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-01-20 15:34 [PATCH v8 0/7] i2c-atr and FPDLink Tomi Valkeinen
2023-01-20 15:34 ` [PATCH v8 1/7] i2c: add I2C Address Translator (ATR) support Tomi Valkeinen
2023-01-20 15:34 ` [PATCH v8 2/7] dt-bindings: media: add TI DS90UB913 FPD-Link III Serializer Tomi Valkeinen
2023-01-20 15:34 ` [PATCH v8 3/7] dt-bindings: media: add TI DS90UB953 " Tomi Valkeinen
2023-01-20 15:34 ` [PATCH v8 4/7] dt-bindings: media: add TI DS90UB960 FPD-Link III Deserializer Tomi Valkeinen
2023-01-20 15:34 ` [PATCH v8 5/7] media: i2c: add DS90UB960 driver Tomi Valkeinen
2023-01-23 22:04   ` Laurent Pinchart
2023-01-24 14:48     ` Tomi Valkeinen
2023-01-24 18:27       ` Laurent Pinchart
2023-01-25  7:39         ` Tomi Valkeinen
2023-01-25 10:13           ` Laurent Pinchart
2023-01-25 11:34             ` Tomi Valkeinen
2023-01-25 11:41             ` Andy Shevchenko
2023-01-20 15:34 ` [PATCH v8 6/7] media: i2c: add DS90UB913 driver Tomi Valkeinen
2023-01-20 15:34 ` [PATCH v8 7/7] media: i2c: add DS90UB953 driver Tomi Valkeinen
2023-01-20 15:37 ` [PATCH v8 0/7] i2c-atr and FPDLink Tomi Valkeinen

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.