Message ID | 1605076797-31058-1-git-send-email-bingbu.cao@intel.com |
---|---|
State | Accepted |
Commit | 798f1a6b0efcb33e5f3abe048aa9d546ca849cd8 |
Headers | show |
Series | [v3,1/2] media: ov2740: only do OTP data read on demand from user | expand |
Hi Bingbu, On Wed, Nov 11, 2020 at 02:39:56PM +0800, Bingbu Cao wrote: > OTP data access of ov2740 in probe need power up, it may cause > the camera flash LED blink during probe if the LED use same power > rail with camera, this patch move the OTP data access out of > probe, it will only occur on demand from user by nvmem sysfs. > > Signed-off-by: Bingbu Cao <bingbu.cao@intel.com> > Signed-off-by: Qingwu Zhang <qingwu.zhang@intel.com> > --- > drivers/media/i2c/ov2740.c | 111 ++++++++++++++++++++++++++++++++------------- > 1 file changed, 79 insertions(+), 32 deletions(-) > With Sakari's comment addressed: Reviewed-by: Tomasz Figa <tfiga@chromium.org> Best regards, Tomasz > diff --git a/drivers/media/i2c/ov2740.c b/drivers/media/i2c/ov2740.c > index 64ecb6917dd3..41c17df46f47 100644 > --- a/drivers/media/i2c/ov2740.c > +++ b/drivers/media/i2c/ov2740.c > @@ -71,9 +71,10 @@ > #define OV2740_REG_OTP_CUSTOMER 0x7010 > > struct nvm_data { > - char *nvm_buffer; > + struct i2c_client *client; > struct nvmem_device *nvmem; > struct regmap *regmap; > + char *nvm_buffer; > }; > > enum { > @@ -335,6 +336,9 @@ struct ov2740 { > > /* Streaming on/off */ > bool streaming; > + > + /* NVM data inforamtion */ > + struct nvm_data *nvm; > }; > > static inline struct ov2740 *to_ov2740(struct v4l2_subdev *subdev) > @@ -930,45 +934,57 @@ static int ov2740_remove(struct i2c_client *client) > return 0; > } > > -static int ov2740_load_otp_data(struct i2c_client *client, struct nvm_data *nvm) > +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 exit; > + 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 exit; > + 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 write ISP CTRL00\n"); > - goto exit; > + 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 write ISP CTRL01\n"); > - goto exit; > + 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 start streaming\n"); > - goto exit; > + dev_err(&client->dev, "failed to set streaming mode\n"); > + goto err; > } > > /* > @@ -981,15 +997,33 @@ static int ov2740_load_otp_data(struct i2c_client *client, struct nvm_data *nvm) > nvm->nvm_buffer, CUSTOMER_USE_OTP_SIZE); > if (ret) { > dev_err(&client->dev, "failed to read OTP data, ret %d\n", ret); > - goto exit; > + goto err; > } > > - ov2740_write_reg(ov2740, OV2740_REG_MODE_SELECT, 1, > - OV2740_MODE_STANDBY); > - ov2740_write_reg(ov2740, OV2740_REG_ISP_CTRL01, 1, isp_ctrl01); > - ov2740_write_reg(ov2740, OV2740_REG_ISP_CTRL00, 1, isp_ctrl00); > + 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; > > -exit: > return ret; > } > > @@ -997,29 +1031,43 @@ static int ov2740_nvmem_read(void *priv, unsigned int off, void *val, > size_t count) > { > struct nvm_data *nvm = priv; > + struct v4l2_subdev *sd = i2c_get_clientdata(nvm->client); > + struct device *dev = &nvm->client->dev; > + struct ov2740 *ov2740 = to_ov2740(sd); > + int ret = 0; > + > + mutex_lock(&ov2740->mutex); > > - memcpy(val, nvm->nvm_buffer + off, count); > + ret = pm_runtime_get_sync(dev); > + if (ret < 0) { > + pm_runtime_put_noidle(dev); > + goto exit; > + } > > - return 0; > + ret = ov2740_load_otp_data(nvm); > + if (!ret) > + memcpy(val, nvm->nvm_buffer + off, count); > + > + pm_runtime_put(dev); > +exit: > + mutex_unlock(&ov2740->mutex); > + return ret; > } > > -static int ov2740_register_nvmem(struct i2c_client *client) > +static int ov2740_register_nvmem(struct i2c_client *client, > + struct ov2740 *ov2740) > { > struct nvm_data *nvm; > struct regmap_config regmap_config = { }; > struct nvmem_config nvmem_config = { }; > struct regmap *regmap; > struct device *dev = &client->dev; > - int ret = 0; > + int ret; > > nvm = devm_kzalloc(dev, sizeof(*nvm), GFP_KERNEL); > if (!nvm) > return -ENOMEM; > > - nvm->nvm_buffer = devm_kzalloc(dev, CUSTOMER_USE_OTP_SIZE, GFP_KERNEL); > - if (!nvm->nvm_buffer) > - return -ENOMEM; > - > regmap_config.val_bits = 8; > regmap_config.reg_bits = 16; > regmap_config.disable_locking = true; > @@ -1028,12 +1076,7 @@ static int ov2740_register_nvmem(struct i2c_client *client) > return PTR_ERR(regmap); > > nvm->regmap = regmap; > - > - ret = ov2740_load_otp_data(client, nvm); > - if (ret) { > - dev_err(dev, "failed to load OTP data, ret %d\n", ret); > - return ret; > - } > + nvm->client = client; > > nvmem_config.name = dev_name(dev); > nvmem_config.dev = dev; > @@ -1051,7 +1094,11 @@ static int ov2740_register_nvmem(struct i2c_client *client) > > nvm->nvmem = devm_nvmem_register(dev, &nvmem_config); > > - return PTR_ERR_OR_ZERO(nvm->nvmem); > + ret = PTR_ERR_OR_ZERO(nvm->nvmem); > + if (!ret) > + ov2740->nvm = nvm; > + > + return ret; > } > > static int ov2740_probe(struct i2c_client *client) > @@ -1103,7 +1150,7 @@ static int ov2740_probe(struct i2c_client *client) > goto probe_error_media_entity_cleanup; > } > > - ret = ov2740_register_nvmem(client); > + ret = ov2740_register_nvmem(client, ov2740); > if (ret) > dev_warn(&client->dev, "register nvmem failed, ret %d\n", ret); > > -- > 2.7.4 >
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@intel.com> > --- > drivers/media/i2c/ov2740.c | 189 +++++++++++++++++++++++---------------------- > 1 file changed, 96 insertions(+), 93 deletions(-) > Reviewed-by: Tomasz Figa <tfiga@chromium.org> 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 >
diff --git a/drivers/media/i2c/ov2740.c b/drivers/media/i2c/ov2740.c index 64ecb6917dd3..41c17df46f47 100644 --- a/drivers/media/i2c/ov2740.c +++ b/drivers/media/i2c/ov2740.c @@ -71,9 +71,10 @@ #define OV2740_REG_OTP_CUSTOMER 0x7010 struct nvm_data { - char *nvm_buffer; + struct i2c_client *client; struct nvmem_device *nvmem; struct regmap *regmap; + char *nvm_buffer; }; enum { @@ -335,6 +336,9 @@ struct ov2740 { /* Streaming on/off */ bool streaming; + + /* NVM data inforamtion */ + struct nvm_data *nvm; }; static inline struct ov2740 *to_ov2740(struct v4l2_subdev *subdev) @@ -930,45 +934,57 @@ static int ov2740_remove(struct i2c_client *client) return 0; } -static int ov2740_load_otp_data(struct i2c_client *client, struct nvm_data *nvm) +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 exit; + 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 exit; + 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 write ISP CTRL00\n"); - goto exit; + 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 write ISP CTRL01\n"); - goto exit; + 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 start streaming\n"); - goto exit; + dev_err(&client->dev, "failed to set streaming mode\n"); + goto err; } /* @@ -981,15 +997,33 @@ static int ov2740_load_otp_data(struct i2c_client *client, struct nvm_data *nvm) nvm->nvm_buffer, CUSTOMER_USE_OTP_SIZE); if (ret) { dev_err(&client->dev, "failed to read OTP data, ret %d\n", ret); - goto exit; + goto err; } - ov2740_write_reg(ov2740, OV2740_REG_MODE_SELECT, 1, - OV2740_MODE_STANDBY); - ov2740_write_reg(ov2740, OV2740_REG_ISP_CTRL01, 1, isp_ctrl01); - ov2740_write_reg(ov2740, OV2740_REG_ISP_CTRL00, 1, isp_ctrl00); + 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; -exit: return ret; } @@ -997,29 +1031,43 @@ static int ov2740_nvmem_read(void *priv, unsigned int off, void *val, size_t count) { struct nvm_data *nvm = priv; + struct v4l2_subdev *sd = i2c_get_clientdata(nvm->client); + struct device *dev = &nvm->client->dev; + struct ov2740 *ov2740 = to_ov2740(sd); + int ret = 0; + + mutex_lock(&ov2740->mutex); - memcpy(val, nvm->nvm_buffer + off, count); + ret = pm_runtime_get_sync(dev); + if (ret < 0) { + pm_runtime_put_noidle(dev); + goto exit; + } - return 0; + ret = ov2740_load_otp_data(nvm); + if (!ret) + memcpy(val, nvm->nvm_buffer + off, count); + + pm_runtime_put(dev); +exit: + mutex_unlock(&ov2740->mutex); + return ret; } -static int ov2740_register_nvmem(struct i2c_client *client) +static int ov2740_register_nvmem(struct i2c_client *client, + struct ov2740 *ov2740) { struct nvm_data *nvm; struct regmap_config regmap_config = { }; struct nvmem_config nvmem_config = { }; struct regmap *regmap; struct device *dev = &client->dev; - int ret = 0; + int ret; nvm = devm_kzalloc(dev, sizeof(*nvm), GFP_KERNEL); if (!nvm) return -ENOMEM; - nvm->nvm_buffer = devm_kzalloc(dev, CUSTOMER_USE_OTP_SIZE, GFP_KERNEL); - if (!nvm->nvm_buffer) - return -ENOMEM; - regmap_config.val_bits = 8; regmap_config.reg_bits = 16; regmap_config.disable_locking = true; @@ -1028,12 +1076,7 @@ static int ov2740_register_nvmem(struct i2c_client *client) return PTR_ERR(regmap); nvm->regmap = regmap; - - ret = ov2740_load_otp_data(client, nvm); - if (ret) { - dev_err(dev, "failed to load OTP data, ret %d\n", ret); - return ret; - } + nvm->client = client; nvmem_config.name = dev_name(dev); nvmem_config.dev = dev; @@ -1051,7 +1094,11 @@ static int ov2740_register_nvmem(struct i2c_client *client) nvm->nvmem = devm_nvmem_register(dev, &nvmem_config); - return PTR_ERR_OR_ZERO(nvm->nvmem); + ret = PTR_ERR_OR_ZERO(nvm->nvmem); + if (!ret) + ov2740->nvm = nvm; + + return ret; } static int ov2740_probe(struct i2c_client *client) @@ -1103,7 +1150,7 @@ static int ov2740_probe(struct i2c_client *client) goto probe_error_media_entity_cleanup; } - ret = ov2740_register_nvmem(client); + ret = ov2740_register_nvmem(client, ov2740); if (ret) dev_warn(&client->dev, "register nvmem failed, ret %d\n", ret);