media: ccs: Implement support for manual LP control
Use the pre_streamon callback to transition the transmitter to either LP-11 or LP-111 mode if supported by the sensor. Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com> Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
This commit is contained in:
committed by
Mauro Carvalho Chehab
parent
253171a0da
commit
41a95d043f
@@ -1943,6 +1943,51 @@ static int ccs_set_stream(struct v4l2_subdev *subdev, int enable)
|
|||||||
return rval;
|
return rval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int ccs_pre_streamon(struct v4l2_subdev *subdev, u32 flags)
|
||||||
|
{
|
||||||
|
struct ccs_sensor *sensor = to_ccs_sensor(subdev);
|
||||||
|
struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd);
|
||||||
|
int rval;
|
||||||
|
|
||||||
|
if (flags & V4L2_SUBDEV_PRE_STREAMON_FL_MANUAL_LP) {
|
||||||
|
switch (sensor->hwcfg.csi_signalling_mode) {
|
||||||
|
case CCS_CSI_SIGNALING_MODE_CSI_2_DPHY:
|
||||||
|
if (!(CCS_LIM(sensor, PHY_CTRL_CAPABILITY_2) &
|
||||||
|
CCS_PHY_CTRL_CAPABILITY_2_MANUAL_LP_DPHY))
|
||||||
|
return -EACCES;
|
||||||
|
break;
|
||||||
|
case CCS_CSI_SIGNALING_MODE_CSI_2_CPHY:
|
||||||
|
if (!(CCS_LIM(sensor, PHY_CTRL_CAPABILITY_2) &
|
||||||
|
CCS_PHY_CTRL_CAPABILITY_2_MANUAL_LP_CPHY))
|
||||||
|
return -EACCES;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return -EACCES;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
rval = ccs_pm_get_init(sensor);
|
||||||
|
if (rval)
|
||||||
|
return rval;
|
||||||
|
|
||||||
|
if (flags & V4L2_SUBDEV_PRE_STREAMON_FL_MANUAL_LP) {
|
||||||
|
rval = ccs_write(sensor, MANUAL_LP_CTRL,
|
||||||
|
CCS_MANUAL_LP_CTRL_ENABLE);
|
||||||
|
if (rval)
|
||||||
|
pm_runtime_put(&client->dev);
|
||||||
|
}
|
||||||
|
|
||||||
|
return rval;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ccs_post_streamoff(struct v4l2_subdev *subdev)
|
||||||
|
{
|
||||||
|
struct ccs_sensor *sensor = to_ccs_sensor(subdev);
|
||||||
|
struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd);
|
||||||
|
|
||||||
|
return pm_runtime_put(&client->dev);
|
||||||
|
}
|
||||||
|
|
||||||
static int ccs_enum_mbus_code(struct v4l2_subdev *subdev,
|
static int ccs_enum_mbus_code(struct v4l2_subdev *subdev,
|
||||||
struct v4l2_subdev_state *sd_state,
|
struct v4l2_subdev_state *sd_state,
|
||||||
struct v4l2_subdev_mbus_code_enum *code)
|
struct v4l2_subdev_mbus_code_enum *code)
|
||||||
@@ -3055,6 +3100,8 @@ static int ccs_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
|
|||||||
|
|
||||||
static const struct v4l2_subdev_video_ops ccs_video_ops = {
|
static const struct v4l2_subdev_video_ops ccs_video_ops = {
|
||||||
.s_stream = ccs_set_stream,
|
.s_stream = ccs_set_stream,
|
||||||
|
.pre_streamon = ccs_pre_streamon,
|
||||||
|
.post_streamoff = ccs_post_streamoff,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct v4l2_subdev_pad_ops ccs_pad_ops = {
|
static const struct v4l2_subdev_pad_ops ccs_pad_ops = {
|
||||||
|
|||||||
Reference in New Issue
Block a user