1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * ADC driver for the Ingenic JZ47xx SoCs 4 * Copyright (c) 2019 Artur Rojek <contact@artur-rojek.eu> 5 * 6 * based on drivers/mfd/jz4740-adc.c 7 */ 8 9 #include <dt-bindings/iio/adc/ingenic,adc.h> 10 #include <linux/clk.h> 11 #include <linux/iio/iio.h> 12 #include <linux/io.h> 13 #include <linux/iopoll.h> 14 #include <linux/kernel.h> 15 #include <linux/module.h> 16 #include <linux/mutex.h> 17 #include <linux/platform_device.h> 18 19 #define JZ_ADC_REG_ENABLE 0x00 20 #define JZ_ADC_REG_CFG 0x04 21 #define JZ_ADC_REG_CTRL 0x08 22 #define JZ_ADC_REG_STATUS 0x0c 23 #define JZ_ADC_REG_ADTCH 0x18 24 #define JZ_ADC_REG_ADBDAT 0x1c 25 #define JZ_ADC_REG_ADSDAT 0x20 26 #define JZ_ADC_REG_ADCLK 0x28 27 28 #define JZ_ADC_REG_CFG_BAT_MD BIT(4) 29 #define JZ_ADC_REG_ADCLK_CLKDIV_LSB 0 30 #define JZ_ADC_REG_ADCLK_CLKDIV10US_LSB 16 31 32 #define JZ_ADC_AUX_VREF 3300 33 #define JZ_ADC_AUX_VREF_BITS 12 34 #define JZ_ADC_BATTERY_LOW_VREF 2500 35 #define JZ_ADC_BATTERY_LOW_VREF_BITS 12 36 #define JZ4725B_ADC_BATTERY_HIGH_VREF 7500 37 #define JZ4725B_ADC_BATTERY_HIGH_VREF_BITS 10 38 #define JZ4740_ADC_BATTERY_HIGH_VREF (7500 * 0.986) 39 #define JZ4740_ADC_BATTERY_HIGH_VREF_BITS 12 40 41 struct ingenic_adc; 42 43 struct ingenic_adc_soc_data { 44 unsigned int battery_high_vref; 45 unsigned int battery_high_vref_bits; 46 const int *battery_raw_avail; 47 size_t battery_raw_avail_size; 48 const int *battery_scale_avail; 49 size_t battery_scale_avail_size; 50 int (*init_clk_div)(struct device *dev, struct ingenic_adc *adc); 51 }; 52 53 struct ingenic_adc { 54 void __iomem *base; 55 struct clk *clk; 56 struct mutex lock; 57 const struct ingenic_adc_soc_data *soc_data; 58 bool low_vref_mode; 59 }; 60 61 static void ingenic_adc_set_config(struct ingenic_adc *adc, 62 uint32_t mask, 63 uint32_t val) 64 { 65 uint32_t cfg; 66 67 clk_enable(adc->clk); 68 mutex_lock(&adc->lock); 69 70 cfg = readl(adc->base + JZ_ADC_REG_CFG) & ~mask; 71 cfg |= val; 72 writel(cfg, adc->base + JZ_ADC_REG_CFG); 73 74 mutex_unlock(&adc->lock); 75 clk_disable(adc->clk); 76 } 77 78 static void ingenic_adc_enable(struct ingenic_adc *adc, 79 int engine, 80 bool enabled) 81 { 82 u8 val; 83 84 mutex_lock(&adc->lock); 85 val = readb(adc->base + JZ_ADC_REG_ENABLE); 86 87 if (enabled) 88 val |= BIT(engine); 89 else 90 val &= ~BIT(engine); 91 92 writeb(val, adc->base + JZ_ADC_REG_ENABLE); 93 mutex_unlock(&adc->lock); 94 } 95 96 static int ingenic_adc_capture(struct ingenic_adc *adc, 97 int engine) 98 { 99 u8 val; 100 int ret; 101 102 ingenic_adc_enable(adc, engine, true); 103 ret = readb_poll_timeout(adc->base + JZ_ADC_REG_ENABLE, val, 104 !(val & BIT(engine)), 250, 1000); 105 if (ret) 106 ingenic_adc_enable(adc, engine, false); 107 108 return ret; 109 } 110 111 static int ingenic_adc_write_raw(struct iio_dev *iio_dev, 112 struct iio_chan_spec const *chan, 113 int val, 114 int val2, 115 long m) 116 { 117 struct ingenic_adc *adc = iio_priv(iio_dev); 118 119 switch (m) { 120 case IIO_CHAN_INFO_SCALE: 121 switch (chan->channel) { 122 case INGENIC_ADC_BATTERY: 123 if (val > JZ_ADC_BATTERY_LOW_VREF) { 124 ingenic_adc_set_config(adc, 125 JZ_ADC_REG_CFG_BAT_MD, 126 0); 127 adc->low_vref_mode = false; 128 } else { 129 ingenic_adc_set_config(adc, 130 JZ_ADC_REG_CFG_BAT_MD, 131 JZ_ADC_REG_CFG_BAT_MD); 132 adc->low_vref_mode = true; 133 } 134 return 0; 135 default: 136 return -EINVAL; 137 } 138 default: 139 return -EINVAL; 140 } 141 } 142 143 static const int jz4725b_adc_battery_raw_avail[] = { 144 0, 1, (1 << JZ_ADC_BATTERY_LOW_VREF_BITS) - 1, 145 }; 146 147 static const int jz4725b_adc_battery_scale_avail[] = { 148 JZ4725B_ADC_BATTERY_HIGH_VREF, JZ4725B_ADC_BATTERY_HIGH_VREF_BITS, 149 JZ_ADC_BATTERY_LOW_VREF, JZ_ADC_BATTERY_LOW_VREF_BITS, 150 }; 151 152 static const int jz4740_adc_battery_raw_avail[] = { 153 0, 1, (1 << JZ_ADC_BATTERY_LOW_VREF_BITS) - 1, 154 }; 155 156 static const int jz4740_adc_battery_scale_avail[] = { 157 JZ4740_ADC_BATTERY_HIGH_VREF, JZ4740_ADC_BATTERY_HIGH_VREF_BITS, 158 JZ_ADC_BATTERY_LOW_VREF, JZ_ADC_BATTERY_LOW_VREF_BITS, 159 }; 160 161 static int jz4725b_adc_init_clk_div(struct device *dev, struct ingenic_adc *adc) 162 { 163 struct clk *parent_clk; 164 unsigned long parent_rate, rate; 165 unsigned int div_main, div_10us; 166 167 parent_clk = clk_get_parent(adc->clk); 168 if (!parent_clk) { 169 dev_err(dev, "ADC clock has no parent\n"); 170 return -ENODEV; 171 } 172 parent_rate = clk_get_rate(parent_clk); 173 174 /* 175 * The JZ4725B ADC works at 500 kHz to 8 MHz. 176 * We pick the highest rate possible. 177 * In practice we typically get 6 MHz, half of the 12 MHz EXT clock. 178 */ 179 div_main = DIV_ROUND_UP(parent_rate, 8000000); 180 div_main = clamp(div_main, 1u, 64u); 181 rate = parent_rate / div_main; 182 if (rate < 500000 || rate > 8000000) { 183 dev_err(dev, "No valid divider for ADC main clock\n"); 184 return -EINVAL; 185 } 186 187 /* We also need a divider that produces a 10us clock. */ 188 div_10us = DIV_ROUND_UP(rate, 100000); 189 190 writel(((div_10us - 1) << JZ_ADC_REG_ADCLK_CLKDIV10US_LSB) | 191 (div_main - 1) << JZ_ADC_REG_ADCLK_CLKDIV_LSB, 192 adc->base + JZ_ADC_REG_ADCLK); 193 194 return 0; 195 } 196 197 static const struct ingenic_adc_soc_data jz4725b_adc_soc_data = { 198 .battery_high_vref = JZ4725B_ADC_BATTERY_HIGH_VREF, 199 .battery_high_vref_bits = JZ4725B_ADC_BATTERY_HIGH_VREF_BITS, 200 .battery_raw_avail = jz4725b_adc_battery_raw_avail, 201 .battery_raw_avail_size = ARRAY_SIZE(jz4725b_adc_battery_raw_avail), 202 .battery_scale_avail = jz4725b_adc_battery_scale_avail, 203 .battery_scale_avail_size = ARRAY_SIZE(jz4725b_adc_battery_scale_avail), 204 .init_clk_div = jz4725b_adc_init_clk_div, 205 }; 206 207 static const struct ingenic_adc_soc_data jz4740_adc_soc_data = { 208 .battery_high_vref = JZ4740_ADC_BATTERY_HIGH_VREF, 209 .battery_high_vref_bits = JZ4740_ADC_BATTERY_HIGH_VREF_BITS, 210 .battery_raw_avail = jz4740_adc_battery_raw_avail, 211 .battery_raw_avail_size = ARRAY_SIZE(jz4740_adc_battery_raw_avail), 212 .battery_scale_avail = jz4740_adc_battery_scale_avail, 213 .battery_scale_avail_size = ARRAY_SIZE(jz4740_adc_battery_scale_avail), 214 .init_clk_div = NULL, /* no ADCLK register on JZ4740 */ 215 }; 216 217 static int ingenic_adc_read_avail(struct iio_dev *iio_dev, 218 struct iio_chan_spec const *chan, 219 const int **vals, 220 int *type, 221 int *length, 222 long m) 223 { 224 struct ingenic_adc *adc = iio_priv(iio_dev); 225 226 switch (m) { 227 case IIO_CHAN_INFO_RAW: 228 *type = IIO_VAL_INT; 229 *length = adc->soc_data->battery_raw_avail_size; 230 *vals = adc->soc_data->battery_raw_avail; 231 return IIO_AVAIL_RANGE; 232 case IIO_CHAN_INFO_SCALE: 233 *type = IIO_VAL_FRACTIONAL_LOG2; 234 *length = adc->soc_data->battery_scale_avail_size; 235 *vals = adc->soc_data->battery_scale_avail; 236 return IIO_AVAIL_LIST; 237 default: 238 return -EINVAL; 239 }; 240 } 241 242 static int ingenic_adc_read_raw(struct iio_dev *iio_dev, 243 struct iio_chan_spec const *chan, 244 int *val, 245 int *val2, 246 long m) 247 { 248 struct ingenic_adc *adc = iio_priv(iio_dev); 249 int ret; 250 251 switch (m) { 252 case IIO_CHAN_INFO_RAW: 253 clk_enable(adc->clk); 254 ret = ingenic_adc_capture(adc, chan->channel); 255 if (ret) { 256 clk_disable(adc->clk); 257 return ret; 258 } 259 260 switch (chan->channel) { 261 case INGENIC_ADC_AUX: 262 *val = readw(adc->base + JZ_ADC_REG_ADSDAT); 263 break; 264 case INGENIC_ADC_BATTERY: 265 *val = readw(adc->base + JZ_ADC_REG_ADBDAT); 266 break; 267 } 268 269 clk_disable(adc->clk); 270 271 return IIO_VAL_INT; 272 case IIO_CHAN_INFO_SCALE: 273 switch (chan->channel) { 274 case INGENIC_ADC_AUX: 275 *val = JZ_ADC_AUX_VREF; 276 *val2 = JZ_ADC_AUX_VREF_BITS; 277 break; 278 case INGENIC_ADC_BATTERY: 279 if (adc->low_vref_mode) { 280 *val = JZ_ADC_BATTERY_LOW_VREF; 281 *val2 = JZ_ADC_BATTERY_LOW_VREF_BITS; 282 } else { 283 *val = adc->soc_data->battery_high_vref; 284 *val2 = adc->soc_data->battery_high_vref_bits; 285 } 286 break; 287 } 288 289 return IIO_VAL_FRACTIONAL_LOG2; 290 default: 291 return -EINVAL; 292 } 293 } 294 295 static void ingenic_adc_clk_cleanup(void *data) 296 { 297 clk_unprepare(data); 298 } 299 300 static const struct iio_info ingenic_adc_info = { 301 .write_raw = ingenic_adc_write_raw, 302 .read_raw = ingenic_adc_read_raw, 303 .read_avail = ingenic_adc_read_avail, 304 }; 305 306 static const struct iio_chan_spec ingenic_channels[] = { 307 { 308 .extend_name = "aux", 309 .type = IIO_VOLTAGE, 310 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | 311 BIT(IIO_CHAN_INFO_SCALE), 312 .indexed = 1, 313 .channel = INGENIC_ADC_AUX, 314 }, 315 { 316 .extend_name = "battery", 317 .type = IIO_VOLTAGE, 318 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | 319 BIT(IIO_CHAN_INFO_SCALE), 320 .info_mask_separate_available = BIT(IIO_CHAN_INFO_RAW) | 321 BIT(IIO_CHAN_INFO_SCALE), 322 .indexed = 1, 323 .channel = INGENIC_ADC_BATTERY, 324 }, 325 }; 326 327 static int ingenic_adc_probe(struct platform_device *pdev) 328 { 329 struct device *dev = &pdev->dev; 330 struct iio_dev *iio_dev; 331 struct ingenic_adc *adc; 332 struct resource *mem_base; 333 const struct ingenic_adc_soc_data *soc_data; 334 int ret; 335 336 soc_data = device_get_match_data(dev); 337 if (!soc_data) 338 return -EINVAL; 339 340 iio_dev = devm_iio_device_alloc(dev, sizeof(*adc)); 341 if (!iio_dev) 342 return -ENOMEM; 343 344 adc = iio_priv(iio_dev); 345 mutex_init(&adc->lock); 346 adc->soc_data = soc_data; 347 348 mem_base = platform_get_resource(pdev, IORESOURCE_MEM, 0); 349 adc->base = devm_ioremap_resource(dev, mem_base); 350 if (IS_ERR(adc->base)) 351 return PTR_ERR(adc->base); 352 353 adc->clk = devm_clk_get(dev, "adc"); 354 if (IS_ERR(adc->clk)) { 355 dev_err(dev, "Unable to get clock\n"); 356 return PTR_ERR(adc->clk); 357 } 358 359 ret = clk_prepare_enable(adc->clk); 360 if (ret) { 361 dev_err(dev, "Failed to enable clock\n"); 362 return ret; 363 } 364 365 /* Set clock dividers. */ 366 if (soc_data->init_clk_div) { 367 ret = soc_data->init_clk_div(dev, adc); 368 if (ret) { 369 clk_disable_unprepare(adc->clk); 370 return ret; 371 } 372 } 373 374 /* Put hardware in a known passive state. */ 375 writeb(0x00, adc->base + JZ_ADC_REG_ENABLE); 376 writeb(0xff, adc->base + JZ_ADC_REG_CTRL); 377 clk_disable(adc->clk); 378 379 ret = devm_add_action_or_reset(dev, ingenic_adc_clk_cleanup, adc->clk); 380 if (ret) { 381 dev_err(dev, "Unable to add action\n"); 382 return ret; 383 } 384 385 iio_dev->dev.parent = dev; 386 iio_dev->name = "jz-adc"; 387 iio_dev->modes = INDIO_DIRECT_MODE; 388 iio_dev->channels = ingenic_channels; 389 iio_dev->num_channels = ARRAY_SIZE(ingenic_channels); 390 iio_dev->info = &ingenic_adc_info; 391 392 ret = devm_iio_device_register(dev, iio_dev); 393 if (ret) 394 dev_err(dev, "Unable to register IIO device\n"); 395 396 return ret; 397 } 398 399 #ifdef CONFIG_OF 400 static const struct of_device_id ingenic_adc_of_match[] = { 401 { .compatible = "ingenic,jz4725b-adc", .data = &jz4725b_adc_soc_data, }, 402 { .compatible = "ingenic,jz4740-adc", .data = &jz4740_adc_soc_data, }, 403 { }, 404 }; 405 MODULE_DEVICE_TABLE(of, ingenic_adc_of_match); 406 #endif 407 408 static struct platform_driver ingenic_adc_driver = { 409 .driver = { 410 .name = "ingenic-adc", 411 .of_match_table = of_match_ptr(ingenic_adc_of_match), 412 }, 413 .probe = ingenic_adc_probe, 414 }; 415 module_platform_driver(ingenic_adc_driver); 416 MODULE_LICENSE("GPL v2"); 417