diff options
Diffstat (limited to 'drivers/media/i2c/ds90ub953.c')
-rw-r--r-- | drivers/media/i2c/ds90ub953.c | 56 |
1 files changed, 41 insertions, 15 deletions
diff --git a/drivers/media/i2c/ds90ub953.c b/drivers/media/i2c/ds90ub953.c index 725589b3e1c5..46569381b332 100644 --- a/drivers/media/i2c/ds90ub953.c +++ b/drivers/media/i2c/ds90ub953.c @@ -65,6 +65,9 @@ #define UB953_REG_GPIO_INPUT_CTRL_OUT_EN(n) BIT(4 + (n)) #define UB953_REG_GPIO_INPUT_CTRL_INPUT_EN(n) BIT(0 + (n)) +#define UB953_REG_BC_CTRL 0x49 +#define UB953_REG_BC_CTRL_CRC_ERR_CLR BIT(3) + #define UB953_REG_REV_MASK_ID 0x50 #define UB953_REG_GENERAL_STATUS 0x52 @@ -397,8 +400,13 @@ static int ub953_gpiochip_probe(struct ub953_data *priv) int ret; /* Set all GPIOs to local input mode */ - ub953_write(priv, UB953_REG_LOCAL_GPIO_DATA, 0); - ub953_write(priv, UB953_REG_GPIO_INPUT_CTRL, 0xf); + ret = ub953_write(priv, UB953_REG_LOCAL_GPIO_DATA, 0); + if (ret) + return ret; + + ret = ub953_write(priv, UB953_REG_GPIO_INPUT_CTRL, 0xf); + if (ret) + return ret; gc->label = dev_name(dev); gc->parent = dev; @@ -618,6 +626,12 @@ static int ub953_log_status(struct v4l2_subdev *sd) ub953_read(priv, UB953_REG_CRC_ERR_CNT2, &v2); dev_info(dev, "CRC error count %u\n", v1 | (v2 << 8)); + /* Clear CRC error counter */ + if (v1 || v2) + regmap_update_bits(priv->regmap, UB953_REG_BC_CTRL, + UB953_REG_BC_CTRL_CRC_ERR_CLR, + UB953_REG_BC_CTRL_CRC_ERR_CLR); + ub953_read(priv, UB953_REG_CSI_ERR_CNT, &v); dev_info(dev, "CSI error count %u\n", v); @@ -958,10 +972,11 @@ static void ub953_calc_clkout_params(struct ub953_data *priv, clkout_data->rate = clkout_rate; } -static void ub953_write_clkout_regs(struct ub953_data *priv, - const struct ub953_clkout_data *clkout_data) +static int ub953_write_clkout_regs(struct ub953_data *priv, + const struct ub953_clkout_data *clkout_data) { u8 clkout_ctrl0, clkout_ctrl1; + int ret; if (priv->hw_data->is_ub971) clkout_ctrl0 = clkout_data->m; @@ -971,8 +986,15 @@ static void ub953_write_clkout_regs(struct ub953_data *priv, clkout_ctrl1 = clkout_data->n; - ub953_write(priv, UB953_REG_CLKOUT_CTRL0, clkout_ctrl0); - ub953_write(priv, UB953_REG_CLKOUT_CTRL1, clkout_ctrl1); + ret = ub953_write(priv, UB953_REG_CLKOUT_CTRL0, clkout_ctrl0); + if (ret) + return ret; + + ret = ub953_write(priv, UB953_REG_CLKOUT_CTRL1, clkout_ctrl1); + if (ret) + return ret; + + return 0; } static unsigned long ub953_clkout_recalc_rate(struct clk_hw *hw, @@ -1052,9 +1074,7 @@ static int ub953_clkout_set_rate(struct clk_hw *hw, unsigned long rate, dev_dbg(&priv->client->dev, "%s %lu (requested %lu)\n", __func__, clkout_data.rate, rate); - ub953_write_clkout_regs(priv, &clkout_data); - - return 0; + return ub953_write_clkout_regs(priv, &clkout_data); } static const struct clk_ops ub953_clkout_ops = { @@ -1079,7 +1099,9 @@ static int ub953_register_clkout(struct ub953_data *priv) /* Initialize clkout to 25MHz by default */ ub953_calc_clkout_params(priv, UB953_DEFAULT_CLKOUT_RATE, &clkout_data); - ub953_write_clkout_regs(priv, &clkout_data); + ret = ub953_write_clkout_regs(priv, &clkout_data); + if (ret) + return ret; priv->clkout_clk_hw.init = &init; @@ -1226,10 +1248,15 @@ static int ub953_hw_init(struct ub953_data *priv) if (ret) return dev_err_probe(dev, ret, "i2c init failed\n"); - ub953_write(priv, UB953_REG_GENERAL_CFG, - (priv->non_continous_clk ? 0 : UB953_REG_GENERAL_CFG_CONT_CLK) | - ((priv->num_data_lanes - 1) << UB953_REG_GENERAL_CFG_CSI_LANE_SEL_SHIFT) | - UB953_REG_GENERAL_CFG_CRC_TX_GEN_ENABLE); + v = 0; + v |= priv->non_continous_clk ? 0 : UB953_REG_GENERAL_CFG_CONT_CLK; + v |= (priv->num_data_lanes - 1) << + UB953_REG_GENERAL_CFG_CSI_LANE_SEL_SHIFT; + v |= UB953_REG_GENERAL_CFG_CRC_TX_GEN_ENABLE; + + ret = ub953_write(priv, UB953_REG_GENERAL_CFG, v); + if (ret) + return ret; return 0; } @@ -1288,7 +1315,6 @@ 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); } |