summaryrefslogtreecommitdiff
path: root/drivers/media/i2c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/i2c')
-rw-r--r--drivers/media/i2c/ccs-pll.c23
-rw-r--r--drivers/media/i2c/ds90ub913.c4
-rw-r--r--drivers/media/i2c/imx334.c18
-rw-r--r--drivers/media/i2c/imx335.c5
-rw-r--r--drivers/media/i2c/lt6911uxe.c4
-rw-r--r--drivers/media/i2c/ov08x40.c2
-rw-r--r--drivers/media/i2c/ov2740.c4
-rw-r--r--drivers/media/i2c/ov5675.c5
-rw-r--r--drivers/media/i2c/ov8856.c9
-rw-r--r--drivers/media/i2c/tc358743.c4
10 files changed, 52 insertions, 26 deletions
diff --git a/drivers/media/i2c/ccs-pll.c b/drivers/media/i2c/ccs-pll.c
index 34ccda666524..2051f1f29229 100644
--- a/drivers/media/i2c/ccs-pll.c
+++ b/drivers/media/i2c/ccs-pll.c
@@ -312,6 +312,11 @@ __ccs_pll_calculate_vt_tree(struct device *dev,
dev_dbg(dev, "more_mul2: %u\n", more_mul);
pll_fr->pll_multiplier = mul * more_mul;
+ if (pll_fr->pll_multiplier > lim_fr->max_pll_multiplier) {
+ dev_dbg(dev, "pll multiplier %u too high\n",
+ pll_fr->pll_multiplier);
+ return -EINVAL;
+ }
if (pll_fr->pll_multiplier * pll_fr->pll_ip_clk_freq_hz >
lim_fr->max_pll_op_clk_freq_hz)
@@ -397,6 +402,8 @@ static int ccs_pll_calculate_vt_tree(struct device *dev,
min_pre_pll_clk_div = max_t(u16, min_pre_pll_clk_div,
pll->ext_clk_freq_hz /
lim_fr->max_pll_ip_clk_freq_hz);
+ if (!(pll->flags & CCS_PLL_FLAG_EXT_IP_PLL_DIVIDER))
+ min_pre_pll_clk_div = clk_div_even(min_pre_pll_clk_div);
dev_dbg(dev, "vt min/max_pre_pll_clk_div: %u,%u\n",
min_pre_pll_clk_div, max_pre_pll_clk_div);
@@ -435,7 +442,7 @@ static int ccs_pll_calculate_vt_tree(struct device *dev,
return -EINVAL;
}
-static void
+static int
ccs_pll_calculate_vt(struct device *dev, const struct ccs_pll_limits *lim,
const struct ccs_pll_branch_limits_bk *op_lim_bk,
struct ccs_pll *pll, struct ccs_pll_branch_fr *pll_fr,
@@ -558,6 +565,8 @@ ccs_pll_calculate_vt(struct device *dev, const struct ccs_pll_limits *lim,
if (best_pix_div < SHRT_MAX >> 1)
break;
}
+ if (best_pix_div == SHRT_MAX >> 1)
+ return -EINVAL;
pll->vt_bk.sys_clk_div = DIV_ROUND_UP(vt_div, best_pix_div);
pll->vt_bk.pix_clk_div = best_pix_div;
@@ -570,6 +579,8 @@ ccs_pll_calculate_vt(struct device *dev, const struct ccs_pll_limits *lim,
out_calc_pixel_rate:
pll->pixel_rate_pixel_array =
pll->vt_bk.pix_clk_freq_hz * pll->vt_lanes;
+
+ return 0;
}
/*
@@ -792,7 +803,7 @@ int ccs_pll_calculate(struct device *dev, const struct ccs_pll_limits *lim,
op_lim_fr->min_pre_pll_clk_div, op_lim_fr->max_pre_pll_clk_div);
max_op_pre_pll_clk_div =
min_t(u16, op_lim_fr->max_pre_pll_clk_div,
- clk_div_even(pll->ext_clk_freq_hz /
+ DIV_ROUND_UP(pll->ext_clk_freq_hz,
op_lim_fr->min_pll_ip_clk_freq_hz));
min_op_pre_pll_clk_div =
max_t(u16, op_lim_fr->min_pre_pll_clk_div,
@@ -815,6 +826,8 @@ int ccs_pll_calculate(struct device *dev, const struct ccs_pll_limits *lim,
one_or_more(
DIV_ROUND_UP(op_lim_fr->max_pll_op_clk_freq_hz,
pll->ext_clk_freq_hz))));
+ if (!(pll->flags & CCS_PLL_FLAG_EXT_IP_PLL_DIVIDER))
+ min_op_pre_pll_clk_div = clk_div_even(min_op_pre_pll_clk_div);
dev_dbg(dev, "pll_op check: min / max op_pre_pll_clk_div: %u / %u\n",
min_op_pre_pll_clk_div, max_op_pre_pll_clk_div);
@@ -843,8 +856,10 @@ int ccs_pll_calculate(struct device *dev, const struct ccs_pll_limits *lim,
if (pll->flags & CCS_PLL_FLAG_DUAL_PLL)
break;
- ccs_pll_calculate_vt(dev, lim, op_lim_bk, pll, op_pll_fr,
- op_pll_bk, cphy, phy_const);
+ rval = ccs_pll_calculate_vt(dev, lim, op_lim_bk, pll, op_pll_fr,
+ op_pll_bk, cphy, phy_const);
+ if (rval)
+ continue;
rval = check_bk_bounds(dev, lim, pll, PLL_VT);
if (rval)
diff --git a/drivers/media/i2c/ds90ub913.c b/drivers/media/i2c/ds90ub913.c
index fd2d2d5272bf..1445ebbcc9ca 100644
--- a/drivers/media/i2c/ds90ub913.c
+++ b/drivers/media/i2c/ds90ub913.c
@@ -450,10 +450,10 @@ static int ub913_set_fmt(struct v4l2_subdev *sd,
if (!fmt)
return -EINVAL;
- format->format.code = finfo->outcode;
-
*fmt = format->format;
+ fmt->code = finfo->outcode;
+
return 0;
}
diff --git a/drivers/media/i2c/imx334.c b/drivers/media/i2c/imx334.c
index a544fc3df39c..b47cb3b8f368 100644
--- a/drivers/media/i2c/imx334.c
+++ b/drivers/media/i2c/imx334.c
@@ -352,6 +352,12 @@ static const struct imx334_reg mode_3840x2160_regs[] = {
{0x302d, 0x00},
{0x302e, 0x00},
{0x302f, 0x0f},
+ {0x3074, 0xb0},
+ {0x3075, 0x00},
+ {0x308e, 0xb1},
+ {0x308f, 0x00},
+ {0x30d8, 0x20},
+ {0x30d9, 0x12},
{0x3076, 0x70},
{0x3077, 0x08},
{0x3090, 0x70},
@@ -1391,6 +1397,9 @@ static int imx334_probe(struct i2c_client *client)
goto error_handler_free;
}
+ pm_runtime_set_active(imx334->dev);
+ pm_runtime_enable(imx334->dev);
+
ret = v4l2_async_register_subdev_sensor(&imx334->sd);
if (ret < 0) {
dev_err(imx334->dev,
@@ -1398,13 +1407,13 @@ static int imx334_probe(struct i2c_client *client)
goto error_media_entity;
}
- pm_runtime_set_active(imx334->dev);
- pm_runtime_enable(imx334->dev);
pm_runtime_idle(imx334->dev);
return 0;
error_media_entity:
+ pm_runtime_disable(imx334->dev);
+ pm_runtime_set_suspended(imx334->dev);
media_entity_cleanup(&imx334->sd.entity);
error_handler_free:
v4l2_ctrl_handler_free(imx334->sd.ctrl_handler);
@@ -1432,7 +1441,10 @@ static void imx334_remove(struct i2c_client *client)
v4l2_ctrl_handler_free(sd->ctrl_handler);
pm_runtime_disable(&client->dev);
- pm_runtime_suspended(&client->dev);
+ if (!pm_runtime_status_suspended(&client->dev)) {
+ imx334_power_off(&client->dev);
+ pm_runtime_set_suspended(&client->dev);
+ }
mutex_destroy(&imx334->mutex);
}
diff --git a/drivers/media/i2c/imx335.c b/drivers/media/i2c/imx335.c
index 0beb80b8c458..9b4db4cd4929 100644
--- a/drivers/media/i2c/imx335.c
+++ b/drivers/media/i2c/imx335.c
@@ -31,7 +31,7 @@
#define IMX335_REG_CPWAIT_TIME CCI_REG8(0x300d)
#define IMX335_REG_WINMODE CCI_REG8(0x3018)
#define IMX335_REG_HTRIMMING_START CCI_REG16_LE(0x302c)
-#define IMX335_REG_HNUM CCI_REG8(0x302e)
+#define IMX335_REG_HNUM CCI_REG16_LE(0x302e)
/* Lines per frame */
#define IMX335_REG_VMAX CCI_REG24_LE(0x3030)
@@ -660,7 +660,8 @@ static int imx335_enum_frame_size(struct v4l2_subdev *sd,
struct imx335 *imx335 = to_imx335(sd);
u32 code;
- if (fsize->index > ARRAY_SIZE(imx335_mbus_codes))
+ /* Only a single supported_mode available. */
+ if (fsize->index > 0)
return -EINVAL;
code = imx335_get_format_code(imx335, fsize->code);
diff --git a/drivers/media/i2c/lt6911uxe.c b/drivers/media/i2c/lt6911uxe.c
index c5b40bb58a37..24857d683fcf 100644
--- a/drivers/media/i2c/lt6911uxe.c
+++ b/drivers/media/i2c/lt6911uxe.c
@@ -605,10 +605,10 @@ static int lt6911uxe_probe(struct i2c_client *client)
return dev_err_probe(dev, PTR_ERR(lt6911uxe->reset_gpio),
"failed to get reset gpio\n");
- lt6911uxe->irq_gpio = devm_gpiod_get(dev, "readystat", GPIOD_IN);
+ lt6911uxe->irq_gpio = devm_gpiod_get(dev, "hpd", GPIOD_IN);
if (IS_ERR(lt6911uxe->irq_gpio))
return dev_err_probe(dev, PTR_ERR(lt6911uxe->irq_gpio),
- "failed to get ready_stat gpio\n");
+ "failed to get hpd gpio\n");
ret = lt6911uxe_fwnode_parse(lt6911uxe, dev);
if (ret)
diff --git a/drivers/media/i2c/ov08x40.c b/drivers/media/i2c/ov08x40.c
index cf0e41fc3071..54575eea3c49 100644
--- a/drivers/media/i2c/ov08x40.c
+++ b/drivers/media/i2c/ov08x40.c
@@ -1341,7 +1341,7 @@ static int ov08x40_power_on(struct device *dev)
}
gpiod_set_value_cansleep(ov08x->reset_gpio, 0);
- usleep_range(1500, 1800);
+ usleep_range(5000, 5500);
return 0;
diff --git a/drivers/media/i2c/ov2740.c b/drivers/media/i2c/ov2740.c
index 80d151e8ae29..6cf461e3373c 100644
--- a/drivers/media/i2c/ov2740.c
+++ b/drivers/media/i2c/ov2740.c
@@ -1456,12 +1456,12 @@ static int ov2740_probe(struct i2c_client *client)
return 0;
probe_error_v4l2_subdev_cleanup:
+ pm_runtime_disable(&client->dev);
+ pm_runtime_set_suspended(&client->dev);
v4l2_subdev_cleanup(&ov2740->sd);
probe_error_media_entity_cleanup:
media_entity_cleanup(&ov2740->sd.entity);
- pm_runtime_disable(&client->dev);
- pm_runtime_set_suspended(&client->dev);
probe_error_v4l2_ctrl_handler_free:
v4l2_ctrl_handler_free(ov2740->sd.ctrl_handler);
diff --git a/drivers/media/i2c/ov5675.c b/drivers/media/i2c/ov5675.c
index c1081deffc2f..e7aec281e9a4 100644
--- a/drivers/media/i2c/ov5675.c
+++ b/drivers/media/i2c/ov5675.c
@@ -1295,11 +1295,8 @@ static int ov5675_probe(struct i2c_client *client)
return -ENOMEM;
ret = ov5675_get_hwcfg(ov5675, &client->dev);
- if (ret) {
- dev_err(&client->dev, "failed to get HW configuration: %d",
- ret);
+ if (ret)
return ret;
- }
v4l2_i2c_subdev_init(&ov5675->sd, client, &ov5675_subdev_ops);
diff --git a/drivers/media/i2c/ov8856.c b/drivers/media/i2c/ov8856.c
index e6704d018248..4b6874d2a104 100644
--- a/drivers/media/i2c/ov8856.c
+++ b/drivers/media/i2c/ov8856.c
@@ -2276,8 +2276,8 @@ static int ov8856_get_hwcfg(struct ov8856 *ov8856, struct device *dev)
if (!is_acpi_node(fwnode)) {
ov8856->xvclk = devm_clk_get(dev, "xvclk");
if (IS_ERR(ov8856->xvclk)) {
- dev_err(dev, "could not get xvclk clock (%pe)\n",
- ov8856->xvclk);
+ dev_err_probe(dev, PTR_ERR(ov8856->xvclk),
+ "could not get xvclk clock\n");
return PTR_ERR(ov8856->xvclk);
}
@@ -2382,11 +2382,8 @@ static int ov8856_probe(struct i2c_client *client)
return -ENOMEM;
ret = ov8856_get_hwcfg(ov8856, &client->dev);
- if (ret) {
- dev_err(&client->dev, "failed to get HW configuration: %d",
- ret);
+ if (ret)
return ret;
- }
v4l2_i2c_subdev_init(&ov8856->sd, client, &ov8856_subdev_ops);
diff --git a/drivers/media/i2c/tc358743.c b/drivers/media/i2c/tc358743.c
index 2d5f42f11158..dcef93e1a3bc 100644
--- a/drivers/media/i2c/tc358743.c
+++ b/drivers/media/i2c/tc358743.c
@@ -313,6 +313,10 @@ static int tc358743_get_detected_timings(struct v4l2_subdev *sd,
memset(timings, 0, sizeof(struct v4l2_dv_timings));
+ /* if HPD is low, ignore any video */
+ if (!(i2c_rd8(sd, HPD_CTL) & MASK_HPD_OUT0))
+ return -ENOLINK;
+
if (no_signal(sd)) {
v4l2_dbg(1, debug, sd, "%s: no valid signal\n", __func__);
return -ENOLINK;