1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (C) 2018, STMicroelectronics - All Rights Reserved 4 * Author: Fabrice Gasnier <fabrice.gasnier@st.com> 5 * 6 * Originally based on the Linux kernel v4.18 drivers/iio/adc/stm32-adc-core.c. 7 */ 8 9 #include <common.h> 10 #include <asm/io.h> 11 #include <power/regulator.h> 12 #include "stm32-adc-core.h" 13 14 /* STM32H7 - common registers for all ADC instances */ 15 #define STM32H7_ADC_CCR (STM32_ADCX_COMN_OFFSET + 0x08) 16 17 /* STM32H7_ADC_CCR - bit fields */ 18 #define STM32H7_PRESC_SHIFT 18 19 #define STM32H7_PRESC_MASK GENMASK(21, 18) 20 #define STM32H7_CKMODE_SHIFT 16 21 #define STM32H7_CKMODE_MASK GENMASK(17, 16) 22 23 /* STM32 H7 maximum analog clock rate (from datasheet) */ 24 #define STM32H7_ADC_MAX_CLK_RATE 36000000 25 26 /** 27 * struct stm32h7_adc_ck_spec - specification for stm32h7 adc clock 28 * @ckmode: ADC clock mode, Async or sync with prescaler. 29 * @presc: prescaler bitfield for async clock mode 30 * @div: prescaler division ratio 31 */ 32 struct stm32h7_adc_ck_spec { 33 u32 ckmode; 34 u32 presc; 35 int div; 36 }; 37 38 static const struct stm32h7_adc_ck_spec stm32h7_adc_ckmodes_spec[] = { 39 /* 00: CK_ADC[1..3]: Asynchronous clock modes */ 40 { 0, 0, 1 }, 41 { 0, 1, 2 }, 42 { 0, 2, 4 }, 43 { 0, 3, 6 }, 44 { 0, 4, 8 }, 45 { 0, 5, 10 }, 46 { 0, 6, 12 }, 47 { 0, 7, 16 }, 48 { 0, 8, 32 }, 49 { 0, 9, 64 }, 50 { 0, 10, 128 }, 51 { 0, 11, 256 }, 52 /* HCLK used: Synchronous clock modes (1, 2 or 4 prescaler) */ 53 { 1, 0, 1 }, 54 { 2, 0, 2 }, 55 { 3, 0, 4 }, 56 }; 57 58 static int stm32h7_adc_clk_sel(struct udevice *dev, 59 struct stm32_adc_common *common) 60 { 61 u32 ckmode, presc; 62 unsigned long rate; 63 int i, div; 64 65 /* stm32h7 bus clock is common for all ADC instances (mandatory) */ 66 if (!clk_valid(&common->bclk)) { 67 dev_err(dev, "No bclk clock found\n"); 68 return -ENOENT; 69 } 70 71 /* 72 * stm32h7 can use either 'bus' or 'adc' clock for analog circuitry. 73 * So, choice is to have bus clock mandatory and adc clock optional. 74 * If optional 'adc' clock has been found, then try to use it first. 75 */ 76 if (clk_valid(&common->aclk)) { 77 /* 78 * Asynchronous clock modes (e.g. ckmode == 0) 79 * From spec: PLL output musn't exceed max rate 80 */ 81 rate = clk_get_rate(&common->aclk); 82 if (!rate) { 83 dev_err(dev, "Invalid aclk rate: 0\n"); 84 return -EINVAL; 85 } 86 87 for (i = 0; i < ARRAY_SIZE(stm32h7_adc_ckmodes_spec); i++) { 88 ckmode = stm32h7_adc_ckmodes_spec[i].ckmode; 89 presc = stm32h7_adc_ckmodes_spec[i].presc; 90 div = stm32h7_adc_ckmodes_spec[i].div; 91 92 if (ckmode) 93 continue; 94 95 if ((rate / div) <= STM32H7_ADC_MAX_CLK_RATE) 96 goto out; 97 } 98 } 99 100 /* Synchronous clock modes (e.g. ckmode is 1, 2 or 3) */ 101 rate = clk_get_rate(&common->bclk); 102 if (!rate) { 103 dev_err(dev, "Invalid bus clock rate: 0\n"); 104 return -EINVAL; 105 } 106 107 for (i = 0; i < ARRAY_SIZE(stm32h7_adc_ckmodes_spec); i++) { 108 ckmode = stm32h7_adc_ckmodes_spec[i].ckmode; 109 presc = stm32h7_adc_ckmodes_spec[i].presc; 110 div = stm32h7_adc_ckmodes_spec[i].div; 111 112 if (!ckmode) 113 continue; 114 115 if ((rate / div) <= STM32H7_ADC_MAX_CLK_RATE) 116 goto out; 117 } 118 119 dev_err(dev, "clk selection failed\n"); 120 return -EINVAL; 121 122 out: 123 /* rate used later by each ADC instance to control BOOST mode */ 124 common->rate = rate / div; 125 126 /* Set common clock mode and prescaler */ 127 clrsetbits_le32(common->base + STM32H7_ADC_CCR, 128 STM32H7_CKMODE_MASK | STM32H7_PRESC_MASK, 129 ckmode << STM32H7_CKMODE_SHIFT | 130 presc << STM32H7_PRESC_SHIFT); 131 132 dev_dbg(dev, "Using %s clock/%d source at %ld kHz\n", 133 ckmode ? "bus" : "adc", div, common->rate / 1000); 134 135 return 0; 136 } 137 138 static int stm32_adc_core_probe(struct udevice *dev) 139 { 140 struct stm32_adc_common *common = dev_get_priv(dev); 141 int ret; 142 143 common->base = dev_read_addr_ptr(dev); 144 if (!common->base) { 145 dev_err(dev, "can't get address\n"); 146 return -ENOENT; 147 } 148 149 ret = device_get_supply_regulator(dev, "vref-supply", &common->vref); 150 if (ret) { 151 dev_err(dev, "can't get vref-supply: %d\n", ret); 152 return ret; 153 } 154 155 ret = regulator_get_value(common->vref); 156 if (ret < 0) { 157 dev_err(dev, "can't get vref-supply value: %d\n", ret); 158 return ret; 159 } 160 common->vref_uv = ret; 161 162 ret = clk_get_by_name(dev, "adc", &common->aclk); 163 if (!ret) { 164 ret = clk_enable(&common->aclk); 165 if (ret) { 166 dev_err(dev, "Can't enable aclk: %d\n", ret); 167 return ret; 168 } 169 } 170 171 ret = clk_get_by_name(dev, "bus", &common->bclk); 172 if (!ret) { 173 ret = clk_enable(&common->bclk); 174 if (ret) { 175 dev_err(dev, "Can't enable bclk: %d\n", ret); 176 goto err_aclk_disable; 177 } 178 } 179 180 ret = stm32h7_adc_clk_sel(dev, common); 181 if (ret) 182 goto err_bclk_disable; 183 184 return ret; 185 186 err_bclk_disable: 187 if (clk_valid(&common->bclk)) 188 clk_disable(&common->bclk); 189 190 err_aclk_disable: 191 if (clk_valid(&common->aclk)) 192 clk_disable(&common->aclk); 193 194 return ret; 195 } 196 197 static const struct udevice_id stm32_adc_core_ids[] = { 198 { .compatible = "st,stm32h7-adc-core" }, 199 { .compatible = "st,stm32mp1-adc-core" }, 200 {} 201 }; 202 203 U_BOOT_DRIVER(stm32_adc_core) = { 204 .name = "stm32-adc-core", 205 .id = UCLASS_SIMPLE_BUS, 206 .of_match = stm32_adc_core_ids, 207 .probe = stm32_adc_core_probe, 208 .priv_auto_alloc_size = sizeof(struct stm32_adc_common), 209 }; 210