Message ID | 20180128232919.12639-8-embed3d@gmail.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On Mon, Jan 29, 2018 at 12:29:10AM +0100, Philipp Rossak wrote: > This patch reworks the driver to support nvmem calibration cells. > The driver checks if the nvmem calibration is supported and reads out > the nvmem. > > Signed-off-by: Philipp Rossak <embed3d@gmail.com> > --- > drivers/iio/adc/sun4i-gpadc-iio.c | 44 +++++++++++++++++++++++++++++++++++++++ > 1 file changed, 44 insertions(+) > > diff --git a/drivers/iio/adc/sun4i-gpadc-iio.c b/drivers/iio/adc/sun4i-gpadc-iio.c > index ac9ad2f8232f..74eeb5cd5218 100644 > --- a/drivers/iio/adc/sun4i-gpadc-iio.c > +++ b/drivers/iio/adc/sun4i-gpadc-iio.c > @@ -27,6 +27,7 @@ > #include <linux/interrupt.h> > #include <linux/io.h> > #include <linux/module.h> > +#include <linux/nvmem-consumer.h> > #include <linux/of.h> > #include <linux/of_device.h> > #include <linux/platform_device.h> > @@ -74,6 +75,7 @@ struct gpadc_data { > bool has_bus_rst; > bool has_mod_clk; > int sensor_count; > + bool supports_nvmem; I think you should add some documentation along with all the fields you're adding. > }; > > static const struct gpadc_data sun4i_gpadc_data = { > @@ -87,6 +89,7 @@ static const struct gpadc_data sun4i_gpadc_data = { > .sample_start = sun4i_gpadc_sample_start, > .sample_end = sun4i_gpadc_sample_end, > .sensor_count = 1, > + .supports_nvmem = false, That's already its value if you leave it out. > }; > > static const struct gpadc_data sun5i_gpadc_data = { > @@ -100,6 +103,7 @@ static const struct gpadc_data sun5i_gpadc_data = { > .sample_start = sun4i_gpadc_sample_start, > .sample_end = sun4i_gpadc_sample_end, > .sensor_count = 1, > + .supports_nvmem = false, > }; > > static const struct gpadc_data sun6i_gpadc_data = { > @@ -113,6 +117,7 @@ static const struct gpadc_data sun6i_gpadc_data = { > .sample_start = sun4i_gpadc_sample_start, > .sample_end = sun4i_gpadc_sample_end, > .sensor_count = 1, > + .supports_nvmem = false, > }; > > static const struct gpadc_data sun8i_a33_gpadc_data = { > @@ -123,6 +128,7 @@ static const struct gpadc_data sun8i_a33_gpadc_data = { > .sample_start = sun4i_gpadc_sample_start, > .sample_end = sun4i_gpadc_sample_end, > .sensor_count = 1, > + .supports_nvmem = false, > }; > > struct sun4i_gpadc_iio { > @@ -141,6 +147,8 @@ struct sun4i_gpadc_iio { > struct clk *mod_clk; > struct reset_control *reset; > int sensor_id; > + u32 calibration_data[2]; > + bool has_calibration_data[2]; Why do you have two different values here? > /* prevents concurrent reads of temperature and ADC */ > struct mutex mutex; > struct thermal_zone_device *tzd; > @@ -561,6 +569,9 @@ static int sun4i_gpadc_probe_dt(struct platform_device *pdev, > struct resource *mem; > void __iomem *base; > int ret; > + struct nvmem_cell *cell; > + ssize_t cell_size; > + u64 *cell_data; > > info->data = of_device_get_match_data(&pdev->dev); > if (!info->data) > @@ -575,6 +586,39 @@ static int sun4i_gpadc_probe_dt(struct platform_device *pdev, > if (IS_ERR(base)) > return PTR_ERR(base); > > + info->has_calibration_data[0] = false; > + info->has_calibration_data[1] = false; > + > + if (!info->data->supports_nvmem) > + goto no_nvmem; > + > + cell = nvmem_cell_get(&pdev->dev, "calibration"); > + if (IS_ERR(cell)) { > + if (PTR_ERR(cell) == -EPROBE_DEFER) > + return PTR_ERR(cell); > + goto no_nvmem; goto considered evil ? :) > + } > + > + cell_data = (u64 *)nvmem_cell_read(cell, &cell_size); > + nvmem_cell_put(cell); > + switch (cell_size) { > + case 8: > + case 6: > + info->has_calibration_data[1] = true; > + info->calibration_data[1] = be32_to_cpu( > + upper_32_bits(cell_data[0])); > + case 4: > + case 2: > + info->has_calibration_data[0] = true; > + info->calibration_data[0] = be32_to_cpu( > + lower_32_bits(cell_data[0])); Why do you need that switch? Thanks! Maxime
On 29.01.2018 10:40, Maxime Ripard wrote: > On Mon, Jan 29, 2018 at 12:29:10AM +0100, Philipp Rossak wrote: >> This patch reworks the driver to support nvmem calibration cells. >> The driver checks if the nvmem calibration is supported and reads out >> the nvmem. >> >> Signed-off-by: Philipp Rossak <embed3d@gmail.com> >> --- >> drivers/iio/adc/sun4i-gpadc-iio.c | 44 +++++++++++++++++++++++++++++++++++++++ >> 1 file changed, 44 insertions(+) >> >> diff --git a/drivers/iio/adc/sun4i-gpadc-iio.c b/drivers/iio/adc/sun4i-gpadc-iio.c >> index ac9ad2f8232f..74eeb5cd5218 100644 >> --- a/drivers/iio/adc/sun4i-gpadc-iio.c >> +++ b/drivers/iio/adc/sun4i-gpadc-iio.c >> @@ -27,6 +27,7 @@ >> #include <linux/interrupt.h> >> #include <linux/io.h> >> #include <linux/module.h> >> +#include <linux/nvmem-consumer.h> >> #include <linux/of.h> >> #include <linux/of_device.h> >> #include <linux/platform_device.h> >> @@ -74,6 +75,7 @@ struct gpadc_data { >> bool has_bus_rst; >> bool has_mod_clk; >> int sensor_count; >> + bool supports_nvmem; > > I think you should add some documentation along with all the fields > you're adding. ok I will add more informations in the next version into the commit message. > >> }; >> >> static const struct gpadc_data sun4i_gpadc_data = { >> @@ -87,6 +89,7 @@ static const struct gpadc_data sun4i_gpadc_data = { >> .sample_start = sun4i_gpadc_sample_start, >> .sample_end = sun4i_gpadc_sample_end, >> .sensor_count = 1, >> + .supports_nvmem = false, > > That's already its value if you leave it out. > >> }; >> >> static const struct gpadc_data sun5i_gpadc_data = { >> @@ -100,6 +103,7 @@ static const struct gpadc_data sun5i_gpadc_data = { >> .sample_start = sun4i_gpadc_sample_start, >> .sample_end = sun4i_gpadc_sample_end, >> .sensor_count = 1, >> + .supports_nvmem = false, >> }; >> >> static const struct gpadc_data sun6i_gpadc_data = { >> @@ -113,6 +117,7 @@ static const struct gpadc_data sun6i_gpadc_data = { >> .sample_start = sun4i_gpadc_sample_start, >> .sample_end = sun4i_gpadc_sample_end, >> .sensor_count = 1, >> + .supports_nvmem = false, >> }; >> >> static const struct gpadc_data sun8i_a33_gpadc_data = { >> @@ -123,6 +128,7 @@ static const struct gpadc_data sun8i_a33_gpadc_data = { >> .sample_start = sun4i_gpadc_sample_start, >> .sample_end = sun4i_gpadc_sample_end, >> .sensor_count = 1, >> + .supports_nvmem = false, >> }; >> >> struct sun4i_gpadc_iio { >> @@ -141,6 +147,8 @@ struct sun4i_gpadc_iio { >> struct clk *mod_clk; >> struct reset_control *reset; >> int sensor_id; >> + u32 calibration_data[2]; >> + bool has_calibration_data[2]; > > Why do you have two different values here? > I think my idea was too complex! I thought it would be better to check if calibration data was read, and is able to be written to hardware. those information were split per register. I think a u64 should be fine for calibration_data. When I write the calibration data I can check on the sensor count and write only the lower 32 bits if there are less than 3 sensors. Is this ok for you? >> /* prevents concurrent reads of temperature and ADC */ >> struct mutex mutex; >> struct thermal_zone_device *tzd; >> @@ -561,6 +569,9 @@ static int sun4i_gpadc_probe_dt(struct platform_device *pdev, >> struct resource *mem; >> void __iomem *base; >> int ret; >> + struct nvmem_cell *cell; >> + ssize_t cell_size; >> + u64 *cell_data; >> >> info->data = of_device_get_match_data(&pdev->dev); >> if (!info->data) >> @@ -575,6 +586,39 @@ static int sun4i_gpadc_probe_dt(struct platform_device *pdev, >> if (IS_ERR(base)) >> return PTR_ERR(base); >> >> + info->has_calibration_data[0] = false; >> + info->has_calibration_data[1] = false; >> + >> + if (!info->data->supports_nvmem) >> + goto no_nvmem; >> + >> + cell = nvmem_cell_get(&pdev->dev, "calibration"); >> + if (IS_ERR(cell)) { >> + if (PTR_ERR(cell) == -EPROBE_DEFER) >> + return PTR_ERR(cell); >> + goto no_nvmem; > > goto considered evil ? :) > this was a suggestion from Jonatan in version one, to make the code better readable. . >> + } >> + >> + cell_data = (u64 *)nvmem_cell_read(cell, &cell_size); >> + nvmem_cell_put(cell); >> + switch (cell_size) { >> + case 8: >> + case 6: >> + info->has_calibration_data[1] = true; >> + info->calibration_data[1] = be32_to_cpu( >> + upper_32_bits(cell_data[0])); >> + case 4: >> + case 2: >> + info->has_calibration_data[0] = true; >> + info->calibration_data[0] = be32_to_cpu( >> + lower_32_bits(cell_data[0])); > > Why do you need that switch? You are right! The calibration reg seems to be always 64 bit wide. [1] So I will just check for the length of 8. > > Thanks! > Maxime > [1]: http://linux-sunxi.org/SID_Register_Guide#eFUSE Thanks, Philipp -- To unsubscribe from this list: send the line "unsubscribe linux-iio" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Mon, Jan 29, 2018 at 01:33:12PM +0100, Philipp Rossak wrote: > > > static const struct gpadc_data sun4i_gpadc_data = { > > > @@ -87,6 +89,7 @@ static const struct gpadc_data sun4i_gpadc_data = { > > > .sample_start = sun4i_gpadc_sample_start, > > > .sample_end = sun4i_gpadc_sample_end, > > > .sensor_count = 1, > > > + .supports_nvmem = false, > > > > That's already its value if you leave it out. > > > > > }; > > > static const struct gpadc_data sun5i_gpadc_data = { > > > @@ -100,6 +103,7 @@ static const struct gpadc_data sun5i_gpadc_data = { > > > .sample_start = sun4i_gpadc_sample_start, > > > .sample_end = sun4i_gpadc_sample_end, > > > .sensor_count = 1, > > > + .supports_nvmem = false, > > > }; > > > static const struct gpadc_data sun6i_gpadc_data = { > > > @@ -113,6 +117,7 @@ static const struct gpadc_data sun6i_gpadc_data = { > > > .sample_start = sun4i_gpadc_sample_start, > > > .sample_end = sun4i_gpadc_sample_end, > > > .sensor_count = 1, > > > + .supports_nvmem = false, > > > }; > > > static const struct gpadc_data sun8i_a33_gpadc_data = { > > > @@ -123,6 +128,7 @@ static const struct gpadc_data sun8i_a33_gpadc_data = { > > > .sample_start = sun4i_gpadc_sample_start, > > > .sample_end = sun4i_gpadc_sample_end, > > > .sensor_count = 1, > > > + .supports_nvmem = false, > > > }; > > > struct sun4i_gpadc_iio { > > > @@ -141,6 +147,8 @@ struct sun4i_gpadc_iio { > > > struct clk *mod_clk; > > > struct reset_control *reset; > > > int sensor_id; > > > + u32 calibration_data[2]; > > > + bool has_calibration_data[2]; > > > > Why do you have two different values here? > > I think my idea was too complex! I thought it would be better to check if > calibration data was read, and is able to be written to hardware. those > information were split per register. > > I think a u64 should be fine for calibration_data. When I write the > calibration data I can check on the sensor count and write only the lower 32 > bits if there are less than 3 sensors. > > Is this ok for you? I'd need to see the implementation, but make sure that this is documented in your driver :) > > > > /* prevents concurrent reads of temperature and ADC */ > > > struct mutex mutex; > > > struct thermal_zone_device *tzd; > > > @@ -561,6 +569,9 @@ static int sun4i_gpadc_probe_dt(struct platform_device *pdev, > > > struct resource *mem; > > > void __iomem *base; > > > int ret; > > > + struct nvmem_cell *cell; > > > + ssize_t cell_size; > > > + u64 *cell_data; > > > info->data = of_device_get_match_data(&pdev->dev); > > > if (!info->data) > > > @@ -575,6 +586,39 @@ static int sun4i_gpadc_probe_dt(struct platform_device *pdev, > > > if (IS_ERR(base)) > > > return PTR_ERR(base); > > > + info->has_calibration_data[0] = false; > > > + info->has_calibration_data[1] = false; > > > + > > > + if (!info->data->supports_nvmem) > > > + goto no_nvmem; > > > + > > > + cell = nvmem_cell_get(&pdev->dev, "calibration"); > > > + if (IS_ERR(cell)) { > > > + if (PTR_ERR(cell) == -EPROBE_DEFER) > > > + return PTR_ERR(cell); > > > + goto no_nvmem; > > > > goto considered evil ? :) > > this was a suggestion from Jonatan in version one, to make the code better > readable. Isn't if (info->data->supports_nvmem && IS_ERR(cell = nvmem_cell_get())) pretty much the same thing? Maxime
Hi Philipp, Thank you for the patch! Perhaps something to improve: [auto build test WARNING on robh/for-next] [also build test WARNING on v4.15 next-20180126] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system] url: https://github.com/0day-ci/linux/commits/Philipp-Rossak/IIO-based-thermal-sensor-driver-for-Allwinner-H3-and-A83T-SoC/20180201-043415 base: https://git.kernel.org/pub/scm/linux/kernel/git/robh/linux.git for-next reproduce: # apt-get install sparse make ARCH=x86_64 allmodconfig make C=1 CF=-D__CHECK_ENDIAN__ sparse warnings: (new ones prefixed by >>) >> drivers/iio/adc/sun4i-gpadc-iio.c:608:53: sparse: cast to restricted __be32 >> drivers/iio/adc/sun4i-gpadc-iio.c:608:53: sparse: cast to restricted __be32 >> drivers/iio/adc/sun4i-gpadc-iio.c:608:53: sparse: cast to restricted __be32 >> drivers/iio/adc/sun4i-gpadc-iio.c:608:53: sparse: cast to restricted __be32 >> drivers/iio/adc/sun4i-gpadc-iio.c:608:53: sparse: cast to restricted __be32 >> drivers/iio/adc/sun4i-gpadc-iio.c:608:53: sparse: cast to restricted __be32 drivers/iio/adc/sun4i-gpadc-iio.c:613:53: sparse: cast to restricted __be32 drivers/iio/adc/sun4i-gpadc-iio.c:613:53: sparse: cast to restricted __be32 drivers/iio/adc/sun4i-gpadc-iio.c:613:53: sparse: cast to restricted __be32 drivers/iio/adc/sun4i-gpadc-iio.c:613:53: sparse: cast to restricted __be32 drivers/iio/adc/sun4i-gpadc-iio.c:613:53: sparse: cast to restricted __be32 drivers/iio/adc/sun4i-gpadc-iio.c:613:53: sparse: cast to restricted __be32 vim +608 drivers/iio/adc/sun4i-gpadc-iio.c 564 565 static int sun4i_gpadc_probe_dt(struct platform_device *pdev, 566 struct iio_dev *indio_dev) 567 { 568 struct sun4i_gpadc_iio *info = iio_priv(indio_dev); 569 struct resource *mem; 570 void __iomem *base; 571 int ret; 572 struct nvmem_cell *cell; 573 ssize_t cell_size; 574 u64 *cell_data; 575 576 info->data = of_device_get_match_data(&pdev->dev); 577 if (!info->data) 578 return -ENODEV; 579 580 info->no_irq = true; 581 indio_dev->num_channels = ARRAY_SIZE(sun8i_a33_gpadc_channels); 582 indio_dev->channels = sun8i_a33_gpadc_channels; 583 584 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); 585 base = devm_ioremap_resource(&pdev->dev, mem); 586 if (IS_ERR(base)) 587 return PTR_ERR(base); 588 589 info->has_calibration_data[0] = false; 590 info->has_calibration_data[1] = false; 591 592 if (!info->data->supports_nvmem) 593 goto no_nvmem; 594 595 cell = nvmem_cell_get(&pdev->dev, "calibration"); 596 if (IS_ERR(cell)) { 597 if (PTR_ERR(cell) == -EPROBE_DEFER) 598 return PTR_ERR(cell); 599 goto no_nvmem; 600 } 601 602 cell_data = (u64 *)nvmem_cell_read(cell, &cell_size); 603 nvmem_cell_put(cell); 604 switch (cell_size) { 605 case 8: 606 case 6: 607 info->has_calibration_data[1] = true; > 608 info->calibration_data[1] = be32_to_cpu( 609 upper_32_bits(cell_data[0])); 610 case 4: 611 case 2: 612 info->has_calibration_data[0] = true; 613 info->calibration_data[0] = be32_to_cpu( 614 lower_32_bits(cell_data[0])); 615 break; 616 default: 617 break; 618 } 619 620 no_nvmem: 621 622 info->regmap = devm_regmap_init_mmio(&pdev->dev, base, 623 &sun4i_gpadc_regmap_config); 624 if (IS_ERR(info->regmap)) { 625 ret = PTR_ERR(info->regmap); 626 dev_err(&pdev->dev, "failed to init regmap: %d\n", ret); 627 return ret; 628 } 629 630 if (info->data->has_bus_rst) { 631 info->reset = devm_reset_control_get(&pdev->dev, NULL); 632 if (IS_ERR(info->reset)) { 633 ret = PTR_ERR(info->reset); 634 return ret; 635 } 636 637 ret = reset_control_deassert(info->reset); 638 if (ret) 639 return ret; 640 } 641 642 if (info->data->has_bus_clk) { 643 info->bus_clk = devm_clk_get(&pdev->dev, "bus"); 644 if (IS_ERR(info->bus_clk)) { 645 ret = PTR_ERR(info->bus_clk); 646 goto assert_reset; 647 } 648 649 ret = clk_prepare_enable(info->bus_clk); 650 if (ret) 651 goto assert_reset; 652 } 653 654 if (info->data->has_mod_clk) { 655 info->mod_clk = devm_clk_get(&pdev->dev, "mod"); 656 if (IS_ERR(info->mod_clk)) { 657 ret = PTR_ERR(info->mod_clk); 658 goto disable_bus_clk; 659 } 660 661 /* Running at 6MHz */ 662 ret = clk_set_rate(info->mod_clk, 4000000); 663 if (ret) 664 goto disable_bus_clk; 665 666 ret = clk_prepare_enable(info->mod_clk); 667 if (ret) 668 goto disable_bus_clk; 669 } 670 671 if (IS_ENABLED(CONFIG_THERMAL_OF)) 672 info->sensor_device = &pdev->dev; 673 674 return 0; 675 676 disable_bus_clk: 677 clk_disable_unprepare(info->bus_clk); 678 679 assert_reset: 680 reset_control_assert(info->reset); 681 682 return ret; 683 } 684 --- 0-DAY kernel test infrastructure Open Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation -- To unsubscribe from this list: send the line "unsubscribe linux-iio" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
>> >>>> /* prevents concurrent reads of temperature and ADC */ >>>> struct mutex mutex; >>>> struct thermal_zone_device *tzd; >>>> @@ -561,6 +569,9 @@ static int sun4i_gpadc_probe_dt(struct platform_device *pdev, >>>> struct resource *mem; >>>> void __iomem *base; >>>> int ret; >>>> + struct nvmem_cell *cell; >>>> + ssize_t cell_size; >>>> + u64 *cell_data; >>>> info->data = of_device_get_match_data(&pdev->dev); >>>> if (!info->data) >>>> @@ -575,6 +586,39 @@ static int sun4i_gpadc_probe_dt(struct platform_device *pdev, >>>> if (IS_ERR(base)) >>>> return PTR_ERR(base); >>>> + info->has_calibration_data[0] = false; >>>> + info->has_calibration_data[1] = false; >>>> + >>>> + if (!info->data->supports_nvmem) >>>> + goto no_nvmem; >>>> + >>>> + cell = nvmem_cell_get(&pdev->dev, "calibration"); >>>> + if (IS_ERR(cell)) { >>>> + if (PTR_ERR(cell) == -EPROBE_DEFER) >>>> + return PTR_ERR(cell); >>>> + goto no_nvmem; >>> >>> goto considered evil ? :) >> >> this was a suggestion from Jonatan in version one, to make the code better >> readable. > > Isn't > > if (info->data->supports_nvmem && IS_ERR(cell = nvmem_cell_get())) > > pretty much the same thing? > > Maxime > I would say : if (info->data->supports_nvmem && !IS_ERR(cell = nvmem_cell_get())) is the same. This would require an else if statement like this: else if (info->data->supports_nvmem && PTR_ERR(cell) == -EPROBE_DEFER) return PTR_ERR(cell); to avoid errors if the thermal sensor is probed before the sid driver. Philipp -- To unsubscribe from this list: send the line "unsubscribe linux-iio" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
diff --git a/drivers/iio/adc/sun4i-gpadc-iio.c b/drivers/iio/adc/sun4i-gpadc-iio.c index ac9ad2f8232f..74eeb5cd5218 100644 --- a/drivers/iio/adc/sun4i-gpadc-iio.c +++ b/drivers/iio/adc/sun4i-gpadc-iio.c @@ -27,6 +27,7 @@ #include <linux/interrupt.h> #include <linux/io.h> #include <linux/module.h> +#include <linux/nvmem-consumer.h> #include <linux/of.h> #include <linux/of_device.h> #include <linux/platform_device.h> @@ -74,6 +75,7 @@ struct gpadc_data { bool has_bus_rst; bool has_mod_clk; int sensor_count; + bool supports_nvmem; }; static const struct gpadc_data sun4i_gpadc_data = { @@ -87,6 +89,7 @@ static const struct gpadc_data sun4i_gpadc_data = { .sample_start = sun4i_gpadc_sample_start, .sample_end = sun4i_gpadc_sample_end, .sensor_count = 1, + .supports_nvmem = false, }; static const struct gpadc_data sun5i_gpadc_data = { @@ -100,6 +103,7 @@ static const struct gpadc_data sun5i_gpadc_data = { .sample_start = sun4i_gpadc_sample_start, .sample_end = sun4i_gpadc_sample_end, .sensor_count = 1, + .supports_nvmem = false, }; static const struct gpadc_data sun6i_gpadc_data = { @@ -113,6 +117,7 @@ static const struct gpadc_data sun6i_gpadc_data = { .sample_start = sun4i_gpadc_sample_start, .sample_end = sun4i_gpadc_sample_end, .sensor_count = 1, + .supports_nvmem = false, }; static const struct gpadc_data sun8i_a33_gpadc_data = { @@ -123,6 +128,7 @@ static const struct gpadc_data sun8i_a33_gpadc_data = { .sample_start = sun4i_gpadc_sample_start, .sample_end = sun4i_gpadc_sample_end, .sensor_count = 1, + .supports_nvmem = false, }; struct sun4i_gpadc_iio { @@ -141,6 +147,8 @@ struct sun4i_gpadc_iio { struct clk *mod_clk; struct reset_control *reset; int sensor_id; + u32 calibration_data[2]; + bool has_calibration_data[2]; /* prevents concurrent reads of temperature and ADC */ struct mutex mutex; struct thermal_zone_device *tzd; @@ -561,6 +569,9 @@ static int sun4i_gpadc_probe_dt(struct platform_device *pdev, struct resource *mem; void __iomem *base; int ret; + struct nvmem_cell *cell; + ssize_t cell_size; + u64 *cell_data; info->data = of_device_get_match_data(&pdev->dev); if (!info->data) @@ -575,6 +586,39 @@ static int sun4i_gpadc_probe_dt(struct platform_device *pdev, if (IS_ERR(base)) return PTR_ERR(base); + info->has_calibration_data[0] = false; + info->has_calibration_data[1] = false; + + if (!info->data->supports_nvmem) + goto no_nvmem; + + cell = nvmem_cell_get(&pdev->dev, "calibration"); + if (IS_ERR(cell)) { + if (PTR_ERR(cell) == -EPROBE_DEFER) + return PTR_ERR(cell); + goto no_nvmem; + } + + cell_data = (u64 *)nvmem_cell_read(cell, &cell_size); + nvmem_cell_put(cell); + switch (cell_size) { + case 8: + case 6: + info->has_calibration_data[1] = true; + info->calibration_data[1] = be32_to_cpu( + upper_32_bits(cell_data[0])); + case 4: + case 2: + info->has_calibration_data[0] = true; + info->calibration_data[0] = be32_to_cpu( + lower_32_bits(cell_data[0])); + break; + default: + break; + } + +no_nvmem: + info->regmap = devm_regmap_init_mmio(&pdev->dev, base, &sun4i_gpadc_regmap_config); if (IS_ERR(info->regmap)) {
This patch reworks the driver to support nvmem calibration cells. The driver checks if the nvmem calibration is supported and reads out the nvmem. Signed-off-by: Philipp Rossak <embed3d@gmail.com> --- drivers/iio/adc/sun4i-gpadc-iio.c | 44 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+)