Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

iio: adc: stm32-adc: add id registers support

Add support of identification registers to STM32 ADC.

By default the ADC hardware instance number is retrieved from
the compatible configuration data. Get the available ADC number
per ADC block, from hardware configuration register,
when this register exists.

Signed-off-by: Olivier Moysan <olivier.moysan@foss.st.com>
Reviewed-by: Fabrice Gasnier <fabrice.gasnier@foss.st.com>
Link: https://lore.kernel.org/r/20220915135452.1712453-1-olivier.moysan@foss.st.com
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>

authored by

Olivier Moysan and committed by
Jonathan Cameron
54861624 fd8059ec

+87 -3
+56 -3
drivers/iio/adc/stm32-adc-core.c
··· 9 9 * 10 10 */ 11 11 12 + #include <linux/bitfield.h> 12 13 #include <linux/clk.h> 13 14 #include <linux/interrupt.h> 14 15 #include <linux/irqchip/chained_irq.h> ··· 63 62 * @regs: common registers for all instances 64 63 * @clk_sel: clock selection routine 65 64 * @max_clk_rate_hz: maximum analog clock rate (Hz, from datasheet) 65 + * @ipid: adc identification number 66 66 * @has_syscfg: SYSCFG capability flags 67 67 * @num_irqs: number of interrupt lines 68 68 * @num_adcs: maximum number of ADC instances in the common registers ··· 72 70 const struct stm32_adc_common_regs *regs; 73 71 int (*clk_sel)(struct platform_device *, struct stm32_adc_priv *); 74 72 u32 max_clk_rate_hz; 73 + u32 ipid; 75 74 unsigned int has_syscfg; 76 75 unsigned int num_irqs; 77 76 unsigned int num_adcs; ··· 81 78 /** 82 79 * struct stm32_adc_priv - stm32 ADC core private data 83 80 * @irq: irq(s) for ADC block 81 + * @nb_adc_max: actual maximum number of instance per ADC block 84 82 * @domain: irq domain reference 85 83 * @aclk: clock reference for the analog circuitry 86 84 * @bclk: bus clock common for all ADCs, depends on part used ··· 99 95 */ 100 96 struct stm32_adc_priv { 101 97 int irq[STM32_ADC_MAX_ADCS]; 98 + unsigned int nb_adc_max; 102 99 struct irq_domain *domain; 103 100 struct clk *aclk; 104 101 struct clk *bclk; ··· 359 354 * before invoking the interrupt handler (e.g. call ISR only for 360 355 * IRQ-enabled ADCs). 361 356 */ 362 - for (i = 0; i < priv->cfg->num_adcs; i++) { 357 + for (i = 0; i < priv->nb_adc_max; i++) { 363 358 if ((status & priv->cfg->regs->eoc_msk[i] && 364 359 stm32_adc_eoc_enabled(priv, i)) || 365 360 (status & priv->cfg->regs->ovr_msk[i])) ··· 429 424 int hwirq; 430 425 unsigned int i; 431 426 432 - for (hwirq = 0; hwirq < STM32_ADC_MAX_ADCS; hwirq++) 427 + for (hwirq = 0; hwirq < priv->nb_adc_max; hwirq++) 433 428 irq_dispose_mapping(irq_find_mapping(priv->domain, hwirq)); 434 429 irq_domain_remove(priv->domain); 435 430 ··· 647 642 return 0; 648 643 } 649 644 645 + static int stm32_adc_probe_identification(struct platform_device *pdev, 646 + struct stm32_adc_priv *priv) 647 + { 648 + struct device_node *np = pdev->dev.of_node; 649 + struct device_node *child; 650 + const char *compat; 651 + int ret, count = 0; 652 + u32 id, val; 653 + 654 + if (!priv->cfg->ipid) 655 + return 0; 656 + 657 + id = FIELD_GET(STM32MP1_IPIDR_MASK, 658 + readl_relaxed(priv->common.base + STM32MP1_ADC_IPDR)); 659 + if (id != priv->cfg->ipid) { 660 + dev_err(&pdev->dev, "Unexpected IP version: 0x%x", id); 661 + return -EINVAL; 662 + } 663 + 664 + for_each_child_of_node(np, child) { 665 + ret = of_property_read_string(child, "compatible", &compat); 666 + if (ret) 667 + continue; 668 + /* Count child nodes with stm32 adc compatible */ 669 + if (strstr(compat, "st,stm32") && strstr(compat, "adc")) 670 + count++; 671 + } 672 + 673 + val = readl_relaxed(priv->common.base + STM32MP1_ADC_HWCFGR0); 674 + priv->nb_adc_max = FIELD_GET(STM32MP1_ADCNUM_MASK, val); 675 + if (count > priv->nb_adc_max) { 676 + dev_err(&pdev->dev, "Unexpected child number: %d", count); 677 + return -EINVAL; 678 + } 679 + 680 + val = readl_relaxed(priv->common.base + STM32MP1_ADC_VERR); 681 + dev_dbg(&pdev->dev, "ADC version: %lu.%lu\n", 682 + FIELD_GET(STM32MP1_MAJREV_MASK, val), 683 + FIELD_GET(STM32MP1_MINREV_MASK, val)); 684 + 685 + return 0; 686 + } 687 + 650 688 static int stm32_adc_probe(struct platform_device *pdev) 651 689 { 652 690 struct stm32_adc_priv *priv; ··· 709 661 710 662 priv->cfg = (const struct stm32_adc_priv_cfg *) 711 663 of_match_device(dev->driver->of_match_table, dev)->data; 664 + priv->nb_adc_max = priv->cfg->num_adcs; 712 665 spin_lock_init(&priv->common.lock); 713 666 714 667 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); ··· 751 702 ret = stm32_adc_core_hw_start(dev); 752 703 if (ret) 753 704 goto err_pm_stop; 705 + 706 + ret = stm32_adc_probe_identification(pdev, priv); 707 + if (ret < 0) 708 + goto err_hw_stop; 754 709 755 710 ret = regulator_get_voltage(priv->vref); 756 711 if (ret < 0) { ··· 864 811 .clk_sel = stm32h7_adc_clk_sel, 865 812 .max_clk_rate_hz = 36000000, 866 813 .has_syscfg = HAS_VBOOSTER | HAS_ANASWVDD, 814 + .ipid = STM32MP15_IPIDR_NUMBER, 867 815 .num_irqs = 2, 868 - .num_adcs = 2, 869 816 }; 870 817 871 818 static const struct of_device_id stm32_adc_of_match[] = {
+31
drivers/iio/adc/stm32-adc-core.h
··· 24 24 * | 0x300 | Master & Slave common regs | 25 25 * -------------------------------------------------------- 26 26 */ 27 + /* Maximum ADC instances number per ADC block for all supported SoCs */ 27 28 #define STM32_ADC_MAX_ADCS 3 28 29 #define STM32_ADC_OFFSET 0x100 29 30 #define STM32_ADCX_COMN_OFFSET 0x300 ··· 106 105 /* STM32MP1 - ADC2 instance option register */ 107 106 #define STM32MP1_ADC2_OR 0xD0 108 107 108 + /* STM32MP1 - Identification registers */ 109 + #define STM32MP1_ADC_HWCFGR0 0x3F0 110 + #define STM32MP1_ADC_VERR 0x3F4 111 + #define STM32MP1_ADC_IPDR 0x3F8 112 + #define STM32MP1_ADC_SIDR 0x3FC 113 + 109 114 /* STM32H7 - common registers for all ADC instances */ 110 115 #define STM32H7_ADC_CSR (STM32_ADCX_COMN_OFFSET + 0x00) 111 116 #define STM32H7_ADC_CCR (STM32_ADCX_COMN_OFFSET + 0x08) ··· 187 180 188 181 /* STM32MP1_ADC2_OR - bit fields */ 189 182 #define STM32MP1_VDDCOREEN BIT(0) 183 + 184 + /* STM32MP1_ADC_HWCFGR0 - bit fields */ 185 + #define STM32MP1_ADCNUM_SHIFT 0 186 + #define STM32MP1_ADCNUM_MASK GENMASK(3, 0) 187 + #define STM32MP1_MULPIPE_SHIFT 4 188 + #define STM32MP1_MULPIPE_MASK GENMASK(7, 4) 189 + #define STM32MP1_OPBITS_SHIFT 8 190 + #define STM32MP1_OPBITS_MASK GENMASK(11, 8) 191 + #define STM32MP1_IDLEVALUE_SHIFT 12 192 + #define STM32MP1_IDLEVALUE_MASK GENMASK(15, 12) 193 + 194 + /* STM32MP1_ADC_VERR - bit fields */ 195 + #define STM32MP1_MINREV_SHIFT 0 196 + #define STM32MP1_MINREV_MASK GENMASK(3, 0) 197 + #define STM32MP1_MAJREV_SHIFT 4 198 + #define STM32MP1_MAJREV_MASK GENMASK(7, 4) 199 + 200 + /* STM32MP1_ADC_IPDR - bit fields */ 201 + #define STM32MP1_IPIDR_MASK GENMASK(31, 0) 202 + 203 + /* STM32MP1_ADC_SIDR - bit fields */ 204 + #define STM32MP1_SIDR_MASK GENMASK(31, 0) 205 + 206 + #define STM32MP15_IPIDR_NUMBER 0x00110005 190 207 191 208 /** 192 209 * struct stm32_adc_common - stm32 ADC driver common data (for all instances)