1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Aspeed AST2400/2500 ADC 4 * 5 * Copyright (C) 2017 Google, Inc. 6 */ 7 8 #include <linux/clk.h> 9 #include <linux/clk-provider.h> 10 #include <linux/err.h> 11 #include <linux/errno.h> 12 #include <linux/io.h> 13 #include <linux/module.h> 14 #include <linux/of_platform.h> 15 #include <linux/platform_device.h> 16 #include <linux/reset.h> 17 #include <linux/spinlock.h> 18 #include <linux/types.h> 19 20 #include <linux/iio/iio.h> 21 #include <linux/iio/driver.h> 22 #include <linux/iopoll.h> 23 24 #define ASPEED_RESOLUTION_BITS 10 25 #define ASPEED_CLOCKS_PER_SAMPLE 12 26 27 #define ASPEED_REG_ENGINE_CONTROL 0x00 28 #define ASPEED_REG_INTERRUPT_CONTROL 0x04 29 #define ASPEED_REG_VGA_DETECT_CONTROL 0x08 30 #define ASPEED_REG_CLOCK_CONTROL 0x0C 31 #define ASPEED_REG_MAX 0xC0 32 33 #define ASPEED_OPERATION_MODE_POWER_DOWN (0x0 << 1) 34 #define ASPEED_OPERATION_MODE_STANDBY (0x1 << 1) 35 #define ASPEED_OPERATION_MODE_NORMAL (0x7 << 1) 36 37 #define ASPEED_ENGINE_ENABLE BIT(0) 38 39 #define ASPEED_ADC_CTRL_INIT_RDY BIT(8) 40 41 #define ASPEED_ADC_INIT_POLLING_TIME 500 42 #define ASPEED_ADC_INIT_TIMEOUT 500000 43 44 struct aspeed_adc_model_data { 45 const char *model_name; 46 unsigned int min_sampling_rate; // Hz 47 unsigned int max_sampling_rate; // Hz 48 unsigned int vref_voltage; // mV 49 bool wait_init_sequence; 50 }; 51 52 struct aspeed_adc_data { 53 struct device *dev; 54 void __iomem *base; 55 spinlock_t clk_lock; 56 struct clk_hw *clk_prescaler; 57 struct clk_hw *clk_scaler; 58 struct reset_control *rst; 59 }; 60 61 #define ASPEED_CHAN(_idx, _data_reg_addr) { \ 62 .type = IIO_VOLTAGE, \ 63 .indexed = 1, \ 64 .channel = (_idx), \ 65 .address = (_data_reg_addr), \ 66 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ 67 .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | \ 68 BIT(IIO_CHAN_INFO_SAMP_FREQ), \ 69 } 70 71 static const struct iio_chan_spec aspeed_adc_iio_channels[] = { 72 ASPEED_CHAN(0, 0x10), 73 ASPEED_CHAN(1, 0x12), 74 ASPEED_CHAN(2, 0x14), 75 ASPEED_CHAN(3, 0x16), 76 ASPEED_CHAN(4, 0x18), 77 ASPEED_CHAN(5, 0x1A), 78 ASPEED_CHAN(6, 0x1C), 79 ASPEED_CHAN(7, 0x1E), 80 ASPEED_CHAN(8, 0x20), 81 ASPEED_CHAN(9, 0x22), 82 ASPEED_CHAN(10, 0x24), 83 ASPEED_CHAN(11, 0x26), 84 ASPEED_CHAN(12, 0x28), 85 ASPEED_CHAN(13, 0x2A), 86 ASPEED_CHAN(14, 0x2C), 87 ASPEED_CHAN(15, 0x2E), 88 }; 89 90 static int aspeed_adc_read_raw(struct iio_dev *indio_dev, 91 struct iio_chan_spec const *chan, 92 int *val, int *val2, long mask) 93 { 94 struct aspeed_adc_data *data = iio_priv(indio_dev); 95 const struct aspeed_adc_model_data *model_data = 96 of_device_get_match_data(data->dev); 97 98 switch (mask) { 99 case IIO_CHAN_INFO_RAW: 100 *val = readw(data->base + chan->address); 101 return IIO_VAL_INT; 102 103 case IIO_CHAN_INFO_SCALE: 104 *val = model_data->vref_voltage; 105 *val2 = ASPEED_RESOLUTION_BITS; 106 return IIO_VAL_FRACTIONAL_LOG2; 107 108 case IIO_CHAN_INFO_SAMP_FREQ: 109 *val = clk_get_rate(data->clk_scaler->clk) / 110 ASPEED_CLOCKS_PER_SAMPLE; 111 return IIO_VAL_INT; 112 113 default: 114 return -EINVAL; 115 } 116 } 117 118 static int aspeed_adc_write_raw(struct iio_dev *indio_dev, 119 struct iio_chan_spec const *chan, 120 int val, int val2, long mask) 121 { 122 struct aspeed_adc_data *data = iio_priv(indio_dev); 123 const struct aspeed_adc_model_data *model_data = 124 of_device_get_match_data(data->dev); 125 126 switch (mask) { 127 case IIO_CHAN_INFO_SAMP_FREQ: 128 if (val < model_data->min_sampling_rate || 129 val > model_data->max_sampling_rate) 130 return -EINVAL; 131 132 clk_set_rate(data->clk_scaler->clk, 133 val * ASPEED_CLOCKS_PER_SAMPLE); 134 return 0; 135 136 case IIO_CHAN_INFO_SCALE: 137 case IIO_CHAN_INFO_RAW: 138 /* 139 * Technically, these could be written but the only reasons 140 * for doing so seem better handled in userspace. EPERM is 141 * returned to signal this is a policy choice rather than a 142 * hardware limitation. 143 */ 144 return -EPERM; 145 146 default: 147 return -EINVAL; 148 } 149 } 150 151 static int aspeed_adc_reg_access(struct iio_dev *indio_dev, 152 unsigned int reg, unsigned int writeval, 153 unsigned int *readval) 154 { 155 struct aspeed_adc_data *data = iio_priv(indio_dev); 156 157 if (!readval || reg % 4 || reg > ASPEED_REG_MAX) 158 return -EINVAL; 159 160 *readval = readl(data->base + reg); 161 162 return 0; 163 } 164 165 static const struct iio_info aspeed_adc_iio_info = { 166 .read_raw = aspeed_adc_read_raw, 167 .write_raw = aspeed_adc_write_raw, 168 .debugfs_reg_access = aspeed_adc_reg_access, 169 }; 170 171 static int aspeed_adc_probe(struct platform_device *pdev) 172 { 173 struct iio_dev *indio_dev; 174 struct aspeed_adc_data *data; 175 const struct aspeed_adc_model_data *model_data; 176 const char *clk_parent_name; 177 int ret; 178 u32 adc_engine_control_reg_val; 179 180 indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*data)); 181 if (!indio_dev) 182 return -ENOMEM; 183 184 data = iio_priv(indio_dev); 185 data->dev = &pdev->dev; 186 187 data->base = devm_platform_ioremap_resource(pdev, 0); 188 if (IS_ERR(data->base)) 189 return PTR_ERR(data->base); 190 191 /* Register ADC clock prescaler with source specified by device tree. */ 192 spin_lock_init(&data->clk_lock); 193 clk_parent_name = of_clk_get_parent_name(pdev->dev.of_node, 0); 194 195 data->clk_prescaler = clk_hw_register_divider( 196 &pdev->dev, "prescaler", clk_parent_name, 0, 197 data->base + ASPEED_REG_CLOCK_CONTROL, 198 17, 15, 0, &data->clk_lock); 199 if (IS_ERR(data->clk_prescaler)) 200 return PTR_ERR(data->clk_prescaler); 201 202 /* 203 * Register ADC clock scaler downstream from the prescaler. Allow rate 204 * setting to adjust the prescaler as well. 205 */ 206 data->clk_scaler = clk_hw_register_divider( 207 &pdev->dev, "scaler", "prescaler", 208 CLK_SET_RATE_PARENT, 209 data->base + ASPEED_REG_CLOCK_CONTROL, 210 0, 10, 0, &data->clk_lock); 211 if (IS_ERR(data->clk_scaler)) { 212 ret = PTR_ERR(data->clk_scaler); 213 goto scaler_error; 214 } 215 216 data->rst = devm_reset_control_get_exclusive(&pdev->dev, NULL); 217 if (IS_ERR(data->rst)) { 218 dev_err(&pdev->dev, 219 "invalid or missing reset controller device tree entry"); 220 ret = PTR_ERR(data->rst); 221 goto reset_error; 222 } 223 reset_control_deassert(data->rst); 224 225 model_data = of_device_get_match_data(&pdev->dev); 226 227 if (model_data->wait_init_sequence) { 228 /* Enable engine in normal mode. */ 229 writel(ASPEED_OPERATION_MODE_NORMAL | ASPEED_ENGINE_ENABLE, 230 data->base + ASPEED_REG_ENGINE_CONTROL); 231 232 /* Wait for initial sequence complete. */ 233 ret = readl_poll_timeout(data->base + ASPEED_REG_ENGINE_CONTROL, 234 adc_engine_control_reg_val, 235 adc_engine_control_reg_val & 236 ASPEED_ADC_CTRL_INIT_RDY, 237 ASPEED_ADC_INIT_POLLING_TIME, 238 ASPEED_ADC_INIT_TIMEOUT); 239 if (ret) 240 goto poll_timeout_error; 241 } 242 243 /* Start all channels in normal mode. */ 244 ret = clk_prepare_enable(data->clk_scaler->clk); 245 if (ret) 246 goto clk_enable_error; 247 248 adc_engine_control_reg_val = GENMASK(31, 16) | 249 ASPEED_OPERATION_MODE_NORMAL | ASPEED_ENGINE_ENABLE; 250 writel(adc_engine_control_reg_val, 251 data->base + ASPEED_REG_ENGINE_CONTROL); 252 253 model_data = of_device_get_match_data(&pdev->dev); 254 indio_dev->name = model_data->model_name; 255 indio_dev->info = &aspeed_adc_iio_info; 256 indio_dev->modes = INDIO_DIRECT_MODE; 257 indio_dev->channels = aspeed_adc_iio_channels; 258 indio_dev->num_channels = ARRAY_SIZE(aspeed_adc_iio_channels); 259 260 ret = iio_device_register(indio_dev); 261 if (ret) 262 goto iio_register_error; 263 264 return 0; 265 266 iio_register_error: 267 writel(ASPEED_OPERATION_MODE_POWER_DOWN, 268 data->base + ASPEED_REG_ENGINE_CONTROL); 269 clk_disable_unprepare(data->clk_scaler->clk); 270 clk_enable_error: 271 poll_timeout_error: 272 reset_control_assert(data->rst); 273 reset_error: 274 clk_hw_unregister_divider(data->clk_scaler); 275 scaler_error: 276 clk_hw_unregister_divider(data->clk_prescaler); 277 return ret; 278 } 279 280 static int aspeed_adc_remove(struct platform_device *pdev) 281 { 282 struct iio_dev *indio_dev = platform_get_drvdata(pdev); 283 struct aspeed_adc_data *data = iio_priv(indio_dev); 284 285 iio_device_unregister(indio_dev); 286 writel(ASPEED_OPERATION_MODE_POWER_DOWN, 287 data->base + ASPEED_REG_ENGINE_CONTROL); 288 clk_disable_unprepare(data->clk_scaler->clk); 289 reset_control_assert(data->rst); 290 clk_hw_unregister_divider(data->clk_scaler); 291 clk_hw_unregister_divider(data->clk_prescaler); 292 293 return 0; 294 } 295 296 static const struct aspeed_adc_model_data ast2400_model_data = { 297 .model_name = "ast2400-adc", 298 .vref_voltage = 2500, // mV 299 .min_sampling_rate = 10000, 300 .max_sampling_rate = 500000, 301 }; 302 303 static const struct aspeed_adc_model_data ast2500_model_data = { 304 .model_name = "ast2500-adc", 305 .vref_voltage = 1800, // mV 306 .min_sampling_rate = 1, 307 .max_sampling_rate = 1000000, 308 .wait_init_sequence = true, 309 }; 310 311 static const struct of_device_id aspeed_adc_matches[] = { 312 { .compatible = "aspeed,ast2400-adc", .data = &ast2400_model_data }, 313 { .compatible = "aspeed,ast2500-adc", .data = &ast2500_model_data }, 314 {}, 315 }; 316 MODULE_DEVICE_TABLE(of, aspeed_adc_matches); 317 318 static struct platform_driver aspeed_adc_driver = { 319 .probe = aspeed_adc_probe, 320 .remove = aspeed_adc_remove, 321 .driver = { 322 .name = KBUILD_MODNAME, 323 .of_match_table = aspeed_adc_matches, 324 } 325 }; 326 327 module_platform_driver(aspeed_adc_driver); 328 329 MODULE_AUTHOR("Rick Altherr <raltherr@google.com>"); 330 MODULE_DESCRIPTION("Aspeed AST2400/2500 ADC Driver"); 331 MODULE_LICENSE("GPL"); 332