diff options
Diffstat (limited to 'drivers/media/i2c/imx219.c')
| -rw-r--r-- | drivers/media/i2c/imx219.c | 51 | 
1 files changed, 30 insertions, 21 deletions
| diff --git a/drivers/media/i2c/imx219.c b/drivers/media/i2c/imx219.c index 6e3382b85a90..1054ffedaefd 100644 --- a/drivers/media/i2c/imx219.c +++ b/drivers/media/i2c/imx219.c @@ -1035,29 +1035,47 @@ static int imx219_start_streaming(struct imx219 *imx219)  	const struct imx219_reg_list *reg_list;  	int ret; +	ret = pm_runtime_get_sync(&client->dev); +	if (ret < 0) { +		pm_runtime_put_noidle(&client->dev); +		return ret; +	} +  	/* Apply default values of current mode */  	reg_list = &imx219->mode->reg_list;  	ret = imx219_write_regs(imx219, reg_list->regs, reg_list->num_of_regs);  	if (ret) {  		dev_err(&client->dev, "%s failed to set mode\n", __func__); -		return ret; +		goto err_rpm_put;  	}  	ret = imx219_set_framefmt(imx219);  	if (ret) {  		dev_err(&client->dev, "%s failed to set frame format: %d\n",  			__func__, ret); -		return ret; +		goto err_rpm_put;  	}  	/* Apply customized values from user */  	ret =  __v4l2_ctrl_handler_setup(imx219->sd.ctrl_handler);  	if (ret) -		return ret; +		goto err_rpm_put;  	/* set stream on register */ -	return imx219_write_reg(imx219, IMX219_REG_MODE_SELECT, -				IMX219_REG_VALUE_08BIT, IMX219_MODE_STREAMING); +	ret = imx219_write_reg(imx219, IMX219_REG_MODE_SELECT, +			       IMX219_REG_VALUE_08BIT, IMX219_MODE_STREAMING); +	if (ret) +		goto err_rpm_put; + +	/* vflip and hflip cannot change during streaming */ +	__v4l2_ctrl_grab(imx219->vflip, true); +	__v4l2_ctrl_grab(imx219->hflip, true); + +	return 0; + +err_rpm_put: +	pm_runtime_put(&client->dev); +	return ret;  }  static void imx219_stop_streaming(struct imx219 *imx219) @@ -1070,12 +1088,16 @@ static void imx219_stop_streaming(struct imx219 *imx219)  			       IMX219_REG_VALUE_08BIT, IMX219_MODE_STANDBY);  	if (ret)  		dev_err(&client->dev, "%s failed to set stream\n", __func__); + +	__v4l2_ctrl_grab(imx219->vflip, false); +	__v4l2_ctrl_grab(imx219->hflip, false); + +	pm_runtime_put(&client->dev);  }  static int imx219_set_stream(struct v4l2_subdev *sd, int enable)  {  	struct imx219 *imx219 = to_imx219(sd); -	struct i2c_client *client = v4l2_get_subdevdata(sd);  	int ret = 0;  	mutex_lock(&imx219->mutex); @@ -1085,36 +1107,23 @@ static int imx219_set_stream(struct v4l2_subdev *sd, int enable)  	}  	if (enable) { -		ret = pm_runtime_get_sync(&client->dev); -		if (ret < 0) { -			pm_runtime_put_noidle(&client->dev); -			goto err_unlock; -		} -  		/*  		 * Apply default & customized values  		 * and then start streaming.  		 */  		ret = imx219_start_streaming(imx219);  		if (ret) -			goto err_rpm_put; +			goto err_unlock;  	} else {  		imx219_stop_streaming(imx219); -		pm_runtime_put(&client->dev);  	}  	imx219->streaming = enable; -	/* vflip and hflip cannot change during streaming */ -	__v4l2_ctrl_grab(imx219->vflip, enable); -	__v4l2_ctrl_grab(imx219->hflip, enable); -  	mutex_unlock(&imx219->mutex);  	return ret; -err_rpm_put: -	pm_runtime_put(&client->dev);  err_unlock:  	mutex_unlock(&imx219->mutex); @@ -1528,7 +1537,7 @@ static int imx219_probe(struct i2c_client *client)  		goto error_handler_free;  	} -	ret = v4l2_async_register_subdev_sensor_common(&imx219->sd); +	ret = v4l2_async_register_subdev_sensor(&imx219->sd);  	if (ret < 0) {  		dev_err(dev, "failed to register sensor sub-device: %d\n", ret);  		goto error_media_entity; | 
