summaryrefslogtreecommitdiff
path: root/drivers/media/i2c/imx412.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/i2c/imx412.c')
-rw-r--r--drivers/media/i2c/imx412.c85
1 files changed, 39 insertions, 46 deletions
diff --git a/drivers/media/i2c/imx412.c b/drivers/media/i2c/imx412.c
index c7e862ae4040..b3826f803547 100644
--- a/drivers/media/i2c/imx412.c
+++ b/drivers/media/i2c/imx412.c
@@ -4,7 +4,7 @@
*
* Copyright (C) 2021 Intel Corporation
*/
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
#include <linux/clk.h>
#include <linux/delay.h>
@@ -127,7 +127,6 @@ static const char * const imx412_supply_names[] = {
* @vblank: Vertical blanking in lines
* @cur_mode: Pointer to current selected sensor mode
* @mutex: Mutex for serializing sensor controls
- * @streaming: Flag indicating streaming state
*/
struct imx412 {
struct device *dev;
@@ -149,7 +148,6 @@ struct imx412 {
u32 vblank;
const struct imx412_mode *cur_mode;
struct mutex mutex;
- bool streaming;
};
static const s64 link_freq[] = {
@@ -544,14 +542,13 @@ static int imx412_update_controls(struct imx412 *imx412,
*/
static int imx412_update_exp_gain(struct imx412 *imx412, u32 exposure, u32 gain)
{
- u32 lpfr, shutter;
+ u32 lpfr;
int ret;
lpfr = imx412->vblank + imx412->cur_mode->height;
- shutter = lpfr - exposure;
- dev_dbg(imx412->dev, "Set exp %u, analog gain %u, shutter %u, lpfr %u",
- exposure, gain, shutter, lpfr);
+ dev_dbg(imx412->dev, "Set exp %u, analog gain %u, lpfr %u\n",
+ exposure, gain, lpfr);
ret = imx412_write_reg(imx412, IMX412_REG_HOLD, 1, 1);
if (ret)
@@ -561,7 +558,7 @@ static int imx412_update_exp_gain(struct imx412 *imx412, u32 exposure, u32 gain)
if (ret)
goto error_release_group_hold;
- ret = imx412_write_reg(imx412, IMX412_REG_EXPOSURE_CIT, 2, shutter);
+ ret = imx412_write_reg(imx412, IMX412_REG_EXPOSURE_CIT, 2, exposure);
if (ret)
goto error_release_group_hold;
@@ -597,7 +594,7 @@ static int imx412_set_ctrl(struct v4l2_ctrl *ctrl)
case V4L2_CID_VBLANK:
imx412->vblank = imx412->vblank_ctrl->val;
- dev_dbg(imx412->dev, "Received vblank %u, new lpfr %u",
+ dev_dbg(imx412->dev, "Received vblank %u, new lpfr %u\n",
imx412->vblank,
imx412->vblank + imx412->cur_mode->height);
@@ -616,7 +613,7 @@ static int imx412_set_ctrl(struct v4l2_ctrl *ctrl)
exposure = ctrl->val;
analog_gain = imx412->again_ctrl->val;
- dev_dbg(imx412->dev, "Received exp %u, analog gain %u",
+ dev_dbg(imx412->dev, "Received exp %u, analog gain %u\n",
exposure, analog_gain);
ret = imx412_update_exp_gain(imx412, exposure, analog_gain);
@@ -625,7 +622,7 @@ static int imx412_set_ctrl(struct v4l2_ctrl *ctrl)
break;
default:
- dev_err(imx412->dev, "Invalid control %d", ctrl->id);
+ dev_err(imx412->dev, "Invalid control %d\n", ctrl->id);
ret = -EINVAL;
}
@@ -723,7 +720,7 @@ static int imx412_get_pad_format(struct v4l2_subdev *sd,
if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
struct v4l2_mbus_framefmt *framefmt;
- framefmt = v4l2_subdev_get_try_format(sd, sd_state, fmt->pad);
+ framefmt = v4l2_subdev_state_get_format(sd_state, fmt->pad);
fmt->format = *framefmt;
} else {
imx412_fill_pad_format(imx412, imx412->cur_mode, fmt);
@@ -758,7 +755,7 @@ static int imx412_set_pad_format(struct v4l2_subdev *sd,
if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
struct v4l2_mbus_framefmt *framefmt;
- framefmt = v4l2_subdev_get_try_format(sd, sd_state, fmt->pad);
+ framefmt = v4l2_subdev_state_get_format(sd_state, fmt->pad);
*framefmt = fmt->format;
} else {
ret = imx412_update_controls(imx412, mode);
@@ -772,14 +769,14 @@ static int imx412_set_pad_format(struct v4l2_subdev *sd,
}
/**
- * imx412_init_pad_cfg() - Initialize sub-device pad configuration
+ * imx412_init_state() - Initialize sub-device state
* @sd: pointer to imx412 V4L2 sub-device structure
* @sd_state: V4L2 sub-device configuration
*
* Return: 0 if successful, error code otherwise.
*/
-static int imx412_init_pad_cfg(struct v4l2_subdev *sd,
- struct v4l2_subdev_state *sd_state)
+static int imx412_init_state(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *sd_state)
{
struct imx412 *imx412 = to_imx412(sd);
struct v4l2_subdev_format fmt = { 0 };
@@ -806,14 +803,14 @@ static int imx412_start_streaming(struct imx412 *imx412)
ret = imx412_write_regs(imx412, reg_list->regs,
reg_list->num_of_regs);
if (ret) {
- dev_err(imx412->dev, "fail to write initial registers");
+ dev_err(imx412->dev, "fail to write initial registers\n");
return ret;
}
/* Setup handler will write actual exposure and gain */
ret = __v4l2_ctrl_handler_setup(imx412->sd.ctrl_handler);
if (ret) {
- dev_err(imx412->dev, "fail to setup handler");
+ dev_err(imx412->dev, "fail to setup handler\n");
return ret;
}
@@ -824,7 +821,7 @@ static int imx412_start_streaming(struct imx412 *imx412)
ret = imx412_write_reg(imx412, IMX412_REG_MODE_SELECT,
1, IMX412_MODE_STREAMING);
if (ret) {
- dev_err(imx412->dev, "fail to start streaming");
+ dev_err(imx412->dev, "fail to start streaming\n");
return ret;
}
@@ -857,11 +854,6 @@ static int imx412_set_stream(struct v4l2_subdev *sd, int enable)
mutex_lock(&imx412->mutex);
- if (imx412->streaming == enable) {
- mutex_unlock(&imx412->mutex);
- return 0;
- }
-
if (enable) {
ret = pm_runtime_resume_and_get(imx412->dev);
if (ret)
@@ -875,8 +867,6 @@ static int imx412_set_stream(struct v4l2_subdev *sd, int enable)
pm_runtime_put(imx412->dev);
}
- imx412->streaming = enable;
-
mutex_unlock(&imx412->mutex);
return 0;
@@ -905,7 +895,7 @@ static int imx412_detect(struct imx412 *imx412)
return ret;
if (val != IMX412_ID) {
- dev_err(imx412->dev, "chip id mismatch: %x!=%x",
+ dev_err(imx412->dev, "chip id mismatch: %x!=%x\n",
IMX412_ID, val);
return -ENXIO;
}
@@ -937,21 +927,20 @@ static int imx412_parse_hw_config(struct imx412 *imx412)
imx412->reset_gpio = devm_gpiod_get_optional(imx412->dev, "reset",
GPIOD_OUT_LOW);
if (IS_ERR(imx412->reset_gpio)) {
- dev_err(imx412->dev, "failed to get reset gpio %ld",
- PTR_ERR(imx412->reset_gpio));
+ dev_err(imx412->dev, "failed to get reset gpio %pe\n",
+ imx412->reset_gpio);
return PTR_ERR(imx412->reset_gpio);
}
/* Get sensor input clock */
- imx412->inclk = devm_clk_get(imx412->dev, NULL);
- if (IS_ERR(imx412->inclk)) {
- dev_err(imx412->dev, "could not get inclk");
- return PTR_ERR(imx412->inclk);
- }
+ imx412->inclk = devm_v4l2_sensor_clk_get(imx412->dev, NULL);
+ if (IS_ERR(imx412->inclk))
+ return dev_err_probe(imx412->dev, PTR_ERR(imx412->inclk),
+ "could not get inclk\n");
rate = clk_get_rate(imx412->inclk);
if (rate != IMX412_INCLK_RATE) {
- dev_err(imx412->dev, "inclk frequency mismatch");
+ dev_err(imx412->dev, "inclk frequency mismatch\n");
return -EINVAL;
}
@@ -976,14 +965,14 @@ static int imx412_parse_hw_config(struct imx412 *imx412)
if (bus_cfg.bus.mipi_csi2.num_data_lanes != IMX412_NUM_DATA_LANES) {
dev_err(imx412->dev,
- "number of CSI2 data lanes %d is not supported",
+ "number of CSI2 data lanes %d is not supported\n",
bus_cfg.bus.mipi_csi2.num_data_lanes);
ret = -EINVAL;
goto done_endpoint_free;
}
if (!bus_cfg.nr_of_link_frequencies) {
- dev_err(imx412->dev, "no link frequencies defined");
+ dev_err(imx412->dev, "no link frequencies defined\n");
ret = -EINVAL;
goto done_endpoint_free;
}
@@ -1006,7 +995,6 @@ static const struct v4l2_subdev_video_ops imx412_video_ops = {
};
static const struct v4l2_subdev_pad_ops imx412_pad_ops = {
- .init_cfg = imx412_init_pad_cfg,
.enum_mbus_code = imx412_enum_mbus_code,
.enum_frame_size = imx412_enum_frame_size,
.get_fmt = imx412_get_pad_format,
@@ -1018,6 +1006,10 @@ static const struct v4l2_subdev_ops imx412_subdev_ops = {
.pad = &imx412_pad_ops,
};
+static const struct v4l2_subdev_internal_ops imx412_internal_ops = {
+ .init_state = imx412_init_state,
+};
+
/**
* imx412_power_on() - Sensor power on sequence
* @dev: pointer to i2c device
@@ -1041,7 +1033,7 @@ static int imx412_power_on(struct device *dev)
ret = clk_prepare_enable(imx412->inclk);
if (ret) {
- dev_err(imx412->dev, "fail to enable inclk");
+ dev_err(imx412->dev, "fail to enable inclk\n");
goto error_reset;
}
@@ -1152,7 +1144,7 @@ static int imx412_init_controls(struct imx412 *imx412)
imx412->hblank_ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
if (ctrl_hdlr->error) {
- dev_err(imx412->dev, "control init failed: %d",
+ dev_err(imx412->dev, "control init failed: %d\n",
ctrl_hdlr->error);
v4l2_ctrl_handler_free(ctrl_hdlr);
return ctrl_hdlr->error;
@@ -1186,10 +1178,11 @@ static int imx412_probe(struct i2c_client *client)
/* Initialize subdev */
v4l2_i2c_subdev_init(&imx412->sd, client, &imx412_subdev_ops);
+ imx412->sd.internal_ops = &imx412_internal_ops;
ret = imx412_parse_hw_config(imx412);
if (ret) {
- dev_err(imx412->dev, "HW configuration is not supported");
+ dev_err(imx412->dev, "HW configuration is not supported\n");
return ret;
}
@@ -1197,14 +1190,14 @@ static int imx412_probe(struct i2c_client *client)
ret = imx412_power_on(imx412->dev);
if (ret) {
- dev_err(imx412->dev, "failed to power-on the sensor");
+ dev_err(imx412->dev, "failed to power-on the sensor\n");
goto error_mutex_destroy;
}
/* Check module identity */
ret = imx412_detect(imx412);
if (ret) {
- dev_err(imx412->dev, "failed to find sensor: %d", ret);
+ dev_err(imx412->dev, "failed to find sensor: %d\n", ret);
goto error_power_off;
}
@@ -1214,7 +1207,7 @@ static int imx412_probe(struct i2c_client *client)
ret = imx412_init_controls(imx412);
if (ret) {
- dev_err(imx412->dev, "failed to init controls: %d", ret);
+ dev_err(imx412->dev, "failed to init controls: %d\n", ret);
goto error_power_off;
}
@@ -1228,14 +1221,14 @@ static int imx412_probe(struct i2c_client *client)
imx412->pad.flags = MEDIA_PAD_FL_SOURCE;
ret = media_entity_pads_init(&imx412->sd.entity, 1, &imx412->pad);
if (ret) {
- dev_err(imx412->dev, "failed to init entity pads: %d", ret);
+ dev_err(imx412->dev, "failed to init entity pads: %d\n", ret);
goto error_handler_free;
}
ret = v4l2_async_register_subdev_sensor(&imx412->sd);
if (ret < 0) {
dev_err(imx412->dev,
- "failed to register async subdev: %d", ret);
+ "failed to register async subdev: %d\n", ret);
goto error_media_entity;
}