Re: [PATCH v3 2/2] media: ov2740: allow OTP data access during streaming

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Wed, Nov 11, 2020 at 02:39:57PM +0800, Bingbu Cao wrote:
> OTP data access of ov2740 need enable the streaming mode to load
> and it could be done in any time, so driver need allow the OTP
> data access during streaming instead of return EBUSY, this patch
> try to read the OTP data out in STREAMON if OTP data is not ready
> before first time streaming start.
> 
> Signed-off-by: Bingbu Cao <bingbu.cao@xxxxxxxxx>
> ---
>  drivers/media/i2c/ov2740.c | 189 +++++++++++++++++++++++----------------------
>  1 file changed, 96 insertions(+), 93 deletions(-)
>

Reviewed-by: Tomasz Figa <tfiga@xxxxxxxxxxxx>

Best regards,
Tomasz

> diff --git a/drivers/media/i2c/ov2740.c b/drivers/media/i2c/ov2740.c
> index 41c17df46f47..d723e0e7adf7 100644
> --- a/drivers/media/i2c/ov2740.c
> +++ b/drivers/media/i2c/ov2740.c
> @@ -598,13 +598,109 @@ static void ov2740_update_pad_format(const struct ov2740_mode *mode,
>  	fmt->field = V4L2_FIELD_NONE;
>  }
>  
> +static int ov2740_load_otp_data(struct nvm_data *nvm)
> +{
> +	struct i2c_client *client = nvm->client;
> +	struct ov2740 *ov2740 = to_ov2740(i2c_get_clientdata(client));
> +	u32 isp_ctrl00 = 0;
> +	u32 isp_ctrl01 = 0;
> +	int ret;
> +
> +	if (!nvm)
> +		return -EINVAL;
> +
> +	if (nvm->nvm_buffer)
> +		return 0;
> +
> +	nvm->nvm_buffer = kzalloc(CUSTOMER_USE_OTP_SIZE, GFP_KERNEL);
> +	if (!nvm->nvm_buffer)
> +		return -ENOMEM;
> +
> +	ret = ov2740_read_reg(ov2740, OV2740_REG_ISP_CTRL00, 1, &isp_ctrl00);
> +	if (ret) {
> +		dev_err(&client->dev, "failed to read ISP CTRL00\n");
> +		goto err;
> +	}
> +
> +	ret = ov2740_read_reg(ov2740, OV2740_REG_ISP_CTRL01, 1, &isp_ctrl01);
> +	if (ret) {
> +		dev_err(&client->dev, "failed to read ISP CTRL01\n");
> +		goto err;
> +	}
> +
> +	/* Clear bit 5 of ISP CTRL00 */
> +	ret = ov2740_write_reg(ov2740, OV2740_REG_ISP_CTRL00, 1,
> +			       isp_ctrl00 & ~BIT(5));
> +	if (ret) {
> +		dev_err(&client->dev, "failed to set ISP CTRL00\n");
> +		goto err;
> +	}
> +
> +	/* Clear bit 7 of ISP CTRL01 */
> +	ret = ov2740_write_reg(ov2740, OV2740_REG_ISP_CTRL01, 1,
> +			       isp_ctrl01 & ~BIT(7));
> +	if (ret) {
> +		dev_err(&client->dev, "failed to set ISP CTRL01\n");
> +		goto err;
> +	}
> +
> +	ret = ov2740_write_reg(ov2740, OV2740_REG_MODE_SELECT, 1,
> +			       OV2740_MODE_STREAMING);
> +	if (ret) {
> +		dev_err(&client->dev, "failed to set streaming mode\n");
> +		goto err;
> +	}
> +
> +	/*
> +	 * Users are not allowed to access OTP-related registers and memory
> +	 * during the 20 ms period after streaming starts (0x100 = 0x01).
> +	 */
> +	msleep(20);
> +
> +	ret = regmap_bulk_read(nvm->regmap, OV2740_REG_OTP_CUSTOMER,
> +			       nvm->nvm_buffer, CUSTOMER_USE_OTP_SIZE);
> +	if (ret) {
> +		dev_err(&client->dev, "failed to read OTP data, ret %d\n", ret);
> +		goto err;
> +	}
> +
> +	ret = ov2740_write_reg(ov2740, OV2740_REG_MODE_SELECT, 1,
> +			       OV2740_MODE_STANDBY);
> +	if (ret) {
> +		dev_err(&client->dev, "failed to set streaming mode\n");
> +		goto err;
> +	}
> +
> +	ret = ov2740_write_reg(ov2740, OV2740_REG_ISP_CTRL01, 1, isp_ctrl01);
> +	if (ret) {
> +		dev_err(&client->dev, "failed to set ISP CTRL01\n");
> +		goto err;
> +	}
> +
> +	ret = ov2740_write_reg(ov2740, OV2740_REG_ISP_CTRL00, 1, isp_ctrl00);
> +	if (ret) {
> +		dev_err(&client->dev, "failed to set ISP CTRL00\n");
> +		goto err;
> +	}
> +
> +	return 0;
> +err:
> +	kfree(nvm->nvm_buffer);
> +	nvm->nvm_buffer = NULL;
> +
> +	return ret;
> +}
> +
>  static int ov2740_start_streaming(struct ov2740 *ov2740)
>  {
>  	struct i2c_client *client = v4l2_get_subdevdata(&ov2740->sd);
> +	struct nvm_data *nvm = ov2740->nvm;
>  	const struct ov2740_reg_list *reg_list;
>  	int link_freq_index;
>  	int ret = 0;
>  
> +	ov2740_load_otp_data(nvm);
> +
>  	link_freq_index = ov2740->cur_mode->link_freq_index;
>  	reg_list = &link_freq_configs[link_freq_index].reg_list;
>  	ret = ov2740_write_reg_list(ov2740, reg_list);
> @@ -934,99 +1030,6 @@ static int ov2740_remove(struct i2c_client *client)
>  	return 0;
>  }
>  
> -static int ov2740_load_otp_data(struct nvm_data *nvm)
> -{
> -	struct i2c_client *client = nvm->client;
> -	struct ov2740 *ov2740 = to_ov2740(i2c_get_clientdata(client));
> -	u32 isp_ctrl00 = 0;
> -	u32 isp_ctrl01 = 0;
> -	int ret;
> -
> -	if (!nvm)
> -		return -EINVAL;
> -
> -	if (nvm->nvm_buffer)
> -		return 0;
> -
> -	nvm->nvm_buffer = kzalloc(CUSTOMER_USE_OTP_SIZE, GFP_KERNEL);
> -	if (!nvm->nvm_buffer)
> -		return -ENOMEM;
> -
> -	ret = ov2740_read_reg(ov2740, OV2740_REG_ISP_CTRL00, 1, &isp_ctrl00);
> -	if (ret) {
> -		dev_err(&client->dev, "failed to read ISP CTRL00\n");
> -		goto err;
> -	}
> -
> -	ret = ov2740_read_reg(ov2740, OV2740_REG_ISP_CTRL01, 1, &isp_ctrl01);
> -	if (ret) {
> -		dev_err(&client->dev, "failed to read ISP CTRL01\n");
> -		goto err;
> -	}
> -
> -	/* Clear bit 5 of ISP CTRL00 */
> -	ret = ov2740_write_reg(ov2740, OV2740_REG_ISP_CTRL00, 1,
> -			       isp_ctrl00 & ~BIT(5));
> -	if (ret) {
> -		dev_err(&client->dev, "failed to set ISP CTRL00\n");
> -		goto err;
> -	}
> -
> -	/* Clear bit 7 of ISP CTRL01 */
> -	ret = ov2740_write_reg(ov2740, OV2740_REG_ISP_CTRL01, 1,
> -			       isp_ctrl01 & ~BIT(7));
> -	if (ret) {
> -		dev_err(&client->dev, "failed to set ISP CTRL01\n");
> -		goto err;
> -	}
> -
> -	ret = ov2740_write_reg(ov2740, OV2740_REG_MODE_SELECT, 1,
> -			       OV2740_MODE_STREAMING);
> -	if (ret) {
> -		dev_err(&client->dev, "failed to set streaming mode\n");
> -		goto err;
> -	}
> -
> -	/*
> -	 * Users are not allowed to access OTP-related registers and memory
> -	 * during the 20 ms period after streaming starts (0x100 = 0x01).
> -	 */
> -	msleep(20);
> -
> -	ret = regmap_bulk_read(nvm->regmap, OV2740_REG_OTP_CUSTOMER,
> -			       nvm->nvm_buffer, CUSTOMER_USE_OTP_SIZE);
> -	if (ret) {
> -		dev_err(&client->dev, "failed to read OTP data, ret %d\n", ret);
> -		goto err;
> -	}
> -
> -	ret = ov2740_write_reg(ov2740, OV2740_REG_MODE_SELECT, 1,
> -			       OV2740_MODE_STANDBY);
> -	if (ret) {
> -		dev_err(&client->dev, "failed to set streaming mode\n");
> -		goto err;
> -	}
> -
> -	ret = ov2740_write_reg(ov2740, OV2740_REG_ISP_CTRL01, 1, isp_ctrl01);
> -	if (ret) {
> -		dev_err(&client->dev, "failed to set ISP CTRL01\n");
> -		goto err;
> -	}
> -
> -	ret = ov2740_write_reg(ov2740, OV2740_REG_ISP_CTRL00, 1, isp_ctrl00);
> -	if (ret) {
> -		dev_err(&client->dev, "failed to set ISP CTRL00\n");
> -		goto err;
> -	}
> -
> -	return 0;
> -err:
> -	kfree(nvm->nvm_buffer);
> -	nvm->nvm_buffer = NULL;
> -
> -	return ret;
> -}
> -
>  static int ov2740_nvmem_read(void *priv, unsigned int off, void *val,
>  			     size_t count)
>  {
> -- 
> 2.7.4
> 



[Index of Archives]     [Linux Input]     [Video for Linux]     [Gstreamer Embedded]     [Mplayer Users]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]

  Powered by Linux