@@ -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>;
};
@@ -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",
@@ -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))
@@ -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);
@@ -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,
},
};
@@ -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,