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

Configure Feed

Select the types of activity you want to include in your feed.

iio: adc: add imx93 adc support

The ADC in i.mx93 is a total new ADC IP, add a driver to support
this ADC.

Currently, only support one shot normal conversion triggered by
software. For other mode, will add in future.

Signed-off-by: Haibo Chen <haibo.chen@nxp.com>
Link: https://lore.kernel.org/r/20230117135137.1735536-2-haibo.chen@nxp.com
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>

authored by

Haibo Chen and committed by
Jonathan Cameron
7d02296a 2315b5ce

+498 -1
+3 -1
MAINTAINERS
··· 15020 15020 F: Documentation/devicetree/bindings/iio/adc/nxp,imx8qxp-adc.yaml 15021 15021 F: drivers/iio/adc/imx8qxp-adc.c 15022 15022 15023 - NXP i.MX 7D/6SX/6UL AND VF610 ADC DRIVER 15023 + NXP i.MX 7D/6SX/6UL/93 AND VF610 ADC DRIVER 15024 15024 M: Haibo Chen <haibo.chen@nxp.com> 15025 15025 L: linux-iio@vger.kernel.org 15026 15026 L: linux-imx@nxp.com 15027 15027 S: Maintained 15028 15028 F: Documentation/devicetree/bindings/iio/adc/fsl,imx7d-adc.yaml 15029 15029 F: Documentation/devicetree/bindings/iio/adc/fsl,vf610-adc.yaml 15030 + F: Documentation/devicetree/bindings/iio/adc/nxp,imx93-adc.yaml 15030 15031 F: drivers/iio/adc/imx7d_adc.c 15032 + F: drivers/iio/adc/imx93_adc.c 15031 15033 F: drivers/iio/adc/vf610_adc.c 15032 15034 15033 15035 NXP PF8100/PF8121A/PF8200 PMIC REGULATOR DEVICE DRIVER
+10
drivers/iio/adc/Kconfig
··· 566 566 This driver can also be built as a module. If so, the module will be 567 567 called imx8qxp-adc. 568 568 569 + config IMX93_ADC 570 + tristate "IMX93 ADC driver" 571 + depends on ARCH_MXC || COMPILE_TEST 572 + depends on HAS_IOMEM 573 + help 574 + Say yes here to build support for IMX93 ADC. 575 + 576 + This driver can also be built as a module. If so, the module will be 577 + called imx93_adc. 578 + 569 579 config LP8788_ADC 570 580 tristate "LP8788 ADC driver" 571 581 depends on MFD_LP8788
+1
drivers/iio/adc/Makefile
··· 49 49 obj-$(CONFIG_HX711) += hx711.o 50 50 obj-$(CONFIG_IMX7D_ADC) += imx7d_adc.o 51 51 obj-$(CONFIG_IMX8QXP_ADC) += imx8qxp-adc.o 52 + obj-$(CONFIG_IMX93_ADC) += imx93_adc.o 52 53 obj-$(CONFIG_INA2XX_ADC) += ina2xx-adc.o 53 54 obj-$(CONFIG_INGENIC_ADC) += ingenic-adc.o 54 55 obj-$(CONFIG_INTEL_MRFLD_ADC) += intel_mrfld_adc.o
+484
drivers/iio/adc/imx93_adc.c
··· 1 + // SPDX-License-Identifier: GPL-2.0+ 2 + /* 3 + * NXP i.MX93 ADC driver 4 + * 5 + * Copyright 2023 NXP 6 + */ 7 + 8 + #include <linux/bitfield.h> 9 + #include <linux/clk.h> 10 + #include <linux/completion.h> 11 + #include <linux/err.h> 12 + #include <linux/iio/iio.h> 13 + #include <linux/interrupt.h> 14 + #include <linux/io.h> 15 + #include <linux/iopoll.h> 16 + #include <linux/mod_devicetable.h> 17 + #include <linux/module.h> 18 + #include <linux/platform_device.h> 19 + #include <linux/pm_runtime.h> 20 + #include <linux/regulator/consumer.h> 21 + 22 + #define IMX93_ADC_DRIVER_NAME "imx93-adc" 23 + 24 + /* Register map definition */ 25 + #define IMX93_ADC_MCR 0x00 26 + #define IMX93_ADC_MSR 0x04 27 + #define IMX93_ADC_ISR 0x10 28 + #define IMX93_ADC_IMR 0x20 29 + #define IMX93_ADC_CIMR0 0x24 30 + #define IMX93_ADC_CTR0 0x94 31 + #define IMX93_ADC_NCMR0 0xA4 32 + #define IMX93_ADC_PCDR0 0x100 33 + #define IMX93_ADC_PCDR1 0x104 34 + #define IMX93_ADC_PCDR2 0x108 35 + #define IMX93_ADC_PCDR3 0x10c 36 + #define IMX93_ADC_PCDR4 0x110 37 + #define IMX93_ADC_PCDR5 0x114 38 + #define IMX93_ADC_PCDR6 0x118 39 + #define IMX93_ADC_PCDR7 0x11c 40 + #define IMX93_ADC_CALSTAT 0x39C 41 + 42 + /* ADC bit shift */ 43 + #define IMX93_ADC_MCR_MODE_MASK BIT(29) 44 + #define IMX93_ADC_MCR_NSTART_MASK BIT(24) 45 + #define IMX93_ADC_MCR_CALSTART_MASK BIT(14) 46 + #define IMX93_ADC_MCR_ADCLKSE_MASK BIT(8) 47 + #define IMX93_ADC_MCR_PWDN_MASK BIT(0) 48 + #define IMX93_ADC_MSR_CALFAIL_MASK BIT(30) 49 + #define IMX93_ADC_MSR_CALBUSY_MASK BIT(29) 50 + #define IMX93_ADC_MSR_ADCSTATUS_MASK GENMASK(2, 0) 51 + #define IMX93_ADC_ISR_ECH_MASK BIT(0) 52 + #define IMX93_ADC_ISR_EOC_MASK BIT(1) 53 + #define IMX93_ADC_ISR_EOC_ECH_MASK (IMX93_ADC_ISR_EOC_MASK | \ 54 + IMX93_ADC_ISR_ECH_MASK) 55 + #define IMX93_ADC_IMR_JEOC_MASK BIT(3) 56 + #define IMX93_ADC_IMR_JECH_MASK BIT(2) 57 + #define IMX93_ADC_IMR_EOC_MASK BIT(1) 58 + #define IMX93_ADC_IMR_ECH_MASK BIT(0) 59 + #define IMX93_ADC_PCDR_CDATA_MASK GENMASK(11, 0) 60 + 61 + /* ADC status */ 62 + #define IMX93_ADC_MSR_ADCSTATUS_IDLE 0 63 + #define IMX93_ADC_MSR_ADCSTATUS_POWER_DOWN 1 64 + #define IMX93_ADC_MSR_ADCSTATUS_WAIT_STATE 2 65 + #define IMX93_ADC_MSR_ADCSTATUS_BUSY_IN_CALIBRATION 3 66 + #define IMX93_ADC_MSR_ADCSTATUS_SAMPLE 4 67 + #define IMX93_ADC_MSR_ADCSTATUS_CONVERSION 6 68 + 69 + #define IMX93_ADC_TIMEOUT msecs_to_jiffies(100) 70 + 71 + struct imx93_adc { 72 + struct device *dev; 73 + void __iomem *regs; 74 + struct clk *ipg_clk; 75 + int irq; 76 + struct regulator *vref; 77 + /* lock to protect against multiple access to the device */ 78 + struct mutex lock; 79 + struct completion completion; 80 + }; 81 + 82 + #define IMX93_ADC_CHAN(_idx) { \ 83 + .type = IIO_VOLTAGE, \ 84 + .indexed = 1, \ 85 + .channel = (_idx), \ 86 + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ 87 + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | \ 88 + BIT(IIO_CHAN_INFO_SAMP_FREQ), \ 89 + } 90 + 91 + static const struct iio_chan_spec imx93_adc_iio_channels[] = { 92 + IMX93_ADC_CHAN(0), 93 + IMX93_ADC_CHAN(1), 94 + IMX93_ADC_CHAN(2), 95 + IMX93_ADC_CHAN(3), 96 + }; 97 + 98 + static void imx93_adc_power_down(struct imx93_adc *adc) 99 + { 100 + u32 mcr, msr; 101 + int ret; 102 + 103 + mcr = readl(adc->regs + IMX93_ADC_MCR); 104 + mcr |= FIELD_PREP(IMX93_ADC_MCR_PWDN_MASK, 1); 105 + writel(mcr, adc->regs + IMX93_ADC_MCR); 106 + 107 + ret = readl_poll_timeout(adc->regs + IMX93_ADC_MSR, msr, 108 + ((msr & IMX93_ADC_MSR_ADCSTATUS_MASK) == 109 + IMX93_ADC_MSR_ADCSTATUS_POWER_DOWN), 110 + 1, 50); 111 + if (ret == -ETIMEDOUT) 112 + dev_warn(adc->dev, 113 + "ADC do not in power down mode, current MSR is %x\n", 114 + msr); 115 + } 116 + 117 + static void imx93_adc_power_up(struct imx93_adc *adc) 118 + { 119 + u32 mcr; 120 + 121 + /* bring ADC out of power down state, in idle state */ 122 + mcr = readl(adc->regs + IMX93_ADC_MCR); 123 + mcr &= ~FIELD_PREP(IMX93_ADC_MCR_PWDN_MASK, 1); 124 + writel(mcr, adc->regs + IMX93_ADC_MCR); 125 + } 126 + 127 + static void imx93_adc_config_ad_clk(struct imx93_adc *adc) 128 + { 129 + u32 mcr; 130 + 131 + /* put adc in power down mode */ 132 + imx93_adc_power_down(adc); 133 + 134 + /* config the AD_CLK equal to bus clock */ 135 + mcr = readl(adc->regs + IMX93_ADC_MCR); 136 + mcr |= FIELD_PREP(IMX93_ADC_MCR_ADCLKSE_MASK, 1); 137 + writel(mcr, adc->regs + IMX93_ADC_MCR); 138 + 139 + imx93_adc_power_up(adc); 140 + } 141 + 142 + static int imx93_adc_calibration(struct imx93_adc *adc) 143 + { 144 + u32 mcr, msr; 145 + int ret; 146 + 147 + /* make sure ADC in power down mode */ 148 + imx93_adc_power_down(adc); 149 + 150 + /* config SAR controller operating clock */ 151 + mcr = readl(adc->regs + IMX93_ADC_MCR); 152 + mcr &= ~FIELD_PREP(IMX93_ADC_MCR_ADCLKSE_MASK, 1); 153 + writel(mcr, adc->regs + IMX93_ADC_MCR); 154 + 155 + imx93_adc_power_up(adc); 156 + 157 + /* 158 + * TODO: we use the default TSAMP/NRSMPL/AVGEN in MCR, 159 + * can add the setting of these bit if need in future. 160 + */ 161 + 162 + /* run calibration */ 163 + mcr = readl(adc->regs + IMX93_ADC_MCR); 164 + mcr |= FIELD_PREP(IMX93_ADC_MCR_CALSTART_MASK, 1); 165 + writel(mcr, adc->regs + IMX93_ADC_MCR); 166 + 167 + /* wait calibration to be finished */ 168 + ret = readl_poll_timeout(adc->regs + IMX93_ADC_MSR, msr, 169 + !(msr & IMX93_ADC_MSR_CALBUSY_MASK), 1000, 2000000); 170 + if (ret == -ETIMEDOUT) { 171 + dev_warn(adc->dev, "ADC do not finish calibration in 2 min!\n"); 172 + imx93_adc_power_down(adc); 173 + return ret; 174 + } 175 + 176 + /* check whether calbration is success or not */ 177 + msr = readl(adc->regs + IMX93_ADC_MSR); 178 + if (msr & IMX93_ADC_MSR_CALFAIL_MASK) { 179 + dev_warn(adc->dev, "ADC calibration failed!\n"); 180 + imx93_adc_power_down(adc); 181 + return -EAGAIN; 182 + } 183 + 184 + return 0; 185 + } 186 + 187 + static int imx93_adc_read_channel_conversion(struct imx93_adc *adc, 188 + int channel_number, 189 + int *result) 190 + { 191 + u32 channel; 192 + u32 imr, mcr, pcda; 193 + long ret; 194 + 195 + reinit_completion(&adc->completion); 196 + 197 + /* config channel mask register */ 198 + channel = 1 << channel_number; 199 + writel(channel, adc->regs + IMX93_ADC_NCMR0); 200 + 201 + /* TODO: can config desired sample time in CTRn if need */ 202 + 203 + /* config interrupt mask */ 204 + imr = FIELD_PREP(IMX93_ADC_IMR_EOC_MASK, 1); 205 + writel(imr, adc->regs + IMX93_ADC_IMR); 206 + writel(channel, adc->regs + IMX93_ADC_CIMR0); 207 + 208 + /* config one-shot mode */ 209 + mcr = readl(adc->regs + IMX93_ADC_MCR); 210 + mcr &= ~FIELD_PREP(IMX93_ADC_MCR_MODE_MASK, 1); 211 + writel(mcr, adc->regs + IMX93_ADC_MCR); 212 + 213 + /* start normal conversion */ 214 + mcr = readl(adc->regs + IMX93_ADC_MCR); 215 + mcr |= FIELD_PREP(IMX93_ADC_MCR_NSTART_MASK, 1); 216 + writel(mcr, adc->regs + IMX93_ADC_MCR); 217 + 218 + ret = wait_for_completion_interruptible_timeout(&adc->completion, 219 + IMX93_ADC_TIMEOUT); 220 + if (ret == 0) 221 + return -ETIMEDOUT; 222 + 223 + if (ret < 0) 224 + return ret; 225 + 226 + pcda = readl(adc->regs + IMX93_ADC_PCDR0 + channel_number * 4); 227 + 228 + *result = FIELD_GET(IMX93_ADC_PCDR_CDATA_MASK, pcda); 229 + 230 + return ret; 231 + } 232 + 233 + static int imx93_adc_read_raw(struct iio_dev *indio_dev, 234 + struct iio_chan_spec const *chan, 235 + int *val, int *val2, long mask) 236 + { 237 + struct imx93_adc *adc = iio_priv(indio_dev); 238 + struct device *dev = adc->dev; 239 + long ret; 240 + u32 vref_uv; 241 + 242 + switch (mask) { 243 + case IIO_CHAN_INFO_RAW: 244 + pm_runtime_get_sync(dev); 245 + mutex_lock(&adc->lock); 246 + ret = imx93_adc_read_channel_conversion(adc, chan->channel, val); 247 + mutex_unlock(&adc->lock); 248 + pm_runtime_mark_last_busy(dev); 249 + pm_runtime_put_sync_autosuspend(dev); 250 + if (ret < 0) 251 + return ret; 252 + 253 + return IIO_VAL_INT; 254 + 255 + case IIO_CHAN_INFO_SCALE: 256 + ret = vref_uv = regulator_get_voltage(adc->vref); 257 + if (ret < 0) 258 + return ret; 259 + *val = vref_uv / 1000; 260 + *val2 = 12; 261 + return IIO_VAL_FRACTIONAL_LOG2; 262 + 263 + case IIO_CHAN_INFO_SAMP_FREQ: 264 + *val = clk_get_rate(adc->ipg_clk); 265 + return IIO_VAL_INT; 266 + 267 + default: 268 + return -EINVAL; 269 + } 270 + } 271 + 272 + static irqreturn_t imx93_adc_isr(int irq, void *dev_id) 273 + { 274 + struct imx93_adc *adc = dev_id; 275 + u32 isr, eoc, unexpected; 276 + 277 + isr = readl(adc->regs + IMX93_ADC_ISR); 278 + 279 + if (FIELD_GET(IMX93_ADC_ISR_EOC_ECH_MASK, isr)) { 280 + eoc = isr & IMX93_ADC_ISR_EOC_ECH_MASK; 281 + writel(eoc, adc->regs + IMX93_ADC_ISR); 282 + complete(&adc->completion); 283 + } 284 + 285 + unexpected = isr & ~IMX93_ADC_ISR_EOC_ECH_MASK; 286 + if (unexpected) { 287 + writel(unexpected, adc->regs + IMX93_ADC_ISR); 288 + dev_err(adc->dev, "Unexpected interrupt 0x%08x.\n", unexpected); 289 + return IRQ_NONE; 290 + } 291 + 292 + return IRQ_HANDLED; 293 + } 294 + 295 + static const struct iio_info imx93_adc_iio_info = { 296 + .read_raw = &imx93_adc_read_raw, 297 + }; 298 + 299 + static int imx93_adc_probe(struct platform_device *pdev) 300 + { 301 + struct imx93_adc *adc; 302 + struct iio_dev *indio_dev; 303 + struct device *dev = &pdev->dev; 304 + int ret; 305 + 306 + indio_dev = devm_iio_device_alloc(dev, sizeof(*adc)); 307 + if (!indio_dev) 308 + return dev_err_probe(dev, -ENOMEM, 309 + "Failed allocating iio device\n"); 310 + 311 + adc = iio_priv(indio_dev); 312 + adc->dev = dev; 313 + 314 + mutex_init(&adc->lock); 315 + adc->regs = devm_platform_ioremap_resource(pdev, 0); 316 + if (IS_ERR(adc->regs)) 317 + return dev_err_probe(dev, PTR_ERR(adc->regs), 318 + "Failed geting ioremap resource\n"); 319 + 320 + /* The third irq is for ADC conversion usage */ 321 + adc->irq = platform_get_irq(pdev, 2); 322 + if (adc->irq < 0) 323 + return adc->irq; 324 + 325 + adc->ipg_clk = devm_clk_get(dev, "ipg"); 326 + if (IS_ERR(adc->ipg_clk)) 327 + return dev_err_probe(dev, PTR_ERR(adc->ipg_clk), 328 + "Failed getting clock.\n"); 329 + 330 + adc->vref = devm_regulator_get(dev, "vref"); 331 + if (IS_ERR(adc->vref)) 332 + return dev_err_probe(dev, PTR_ERR(adc->vref), 333 + "Failed getting reference voltage.\n"); 334 + 335 + ret = regulator_enable(adc->vref); 336 + if (ret) 337 + return dev_err_probe(dev, ret, 338 + "Failed to enable reference voltage.\n"); 339 + 340 + platform_set_drvdata(pdev, indio_dev); 341 + 342 + init_completion(&adc->completion); 343 + 344 + indio_dev->name = "imx93-adc"; 345 + indio_dev->info = &imx93_adc_iio_info; 346 + indio_dev->modes = INDIO_DIRECT_MODE; 347 + indio_dev->channels = imx93_adc_iio_channels; 348 + indio_dev->num_channels = ARRAY_SIZE(imx93_adc_iio_channels); 349 + 350 + ret = clk_prepare_enable(adc->ipg_clk); 351 + if (ret) { 352 + dev_err_probe(dev, ret, 353 + "Failed to enable ipg clock.\n"); 354 + goto error_regulator_disable; 355 + } 356 + 357 + ret = request_irq(adc->irq, imx93_adc_isr, 0, IMX93_ADC_DRIVER_NAME, adc); 358 + if (ret < 0) { 359 + dev_err_probe(dev, ret, 360 + "Failed requesting irq, irq = %d\n", adc->irq); 361 + goto error_ipg_clk_disable; 362 + } 363 + 364 + ret = imx93_adc_calibration(adc); 365 + if (ret < 0) 366 + goto error_free_adc_irq; 367 + 368 + imx93_adc_config_ad_clk(adc); 369 + 370 + ret = iio_device_register(indio_dev); 371 + if (ret) { 372 + dev_err_probe(dev, ret, 373 + "Failed to register this iio device.\n"); 374 + goto error_adc_power_down; 375 + } 376 + 377 + pm_runtime_set_active(dev); 378 + pm_runtime_set_autosuspend_delay(dev, 50); 379 + pm_runtime_use_autosuspend(dev); 380 + pm_runtime_enable(dev); 381 + 382 + return 0; 383 + 384 + error_adc_power_down: 385 + imx93_adc_power_down(adc); 386 + error_free_adc_irq: 387 + free_irq(adc->irq, adc); 388 + error_ipg_clk_disable: 389 + clk_disable_unprepare(adc->ipg_clk); 390 + error_regulator_disable: 391 + regulator_disable(adc->vref); 392 + 393 + return ret; 394 + } 395 + 396 + static int imx93_adc_remove(struct platform_device *pdev) 397 + { 398 + struct iio_dev *indio_dev = platform_get_drvdata(pdev); 399 + struct imx93_adc *adc = iio_priv(indio_dev); 400 + struct device *dev = adc->dev; 401 + 402 + /* adc power down need clock on */ 403 + pm_runtime_get_sync(dev); 404 + 405 + pm_runtime_disable(dev); 406 + pm_runtime_dont_use_autosuspend(dev); 407 + pm_runtime_put_noidle(dev); 408 + 409 + iio_device_unregister(indio_dev); 410 + imx93_adc_power_down(adc); 411 + free_irq(adc->irq, adc); 412 + clk_disable_unprepare(adc->ipg_clk); 413 + regulator_disable(adc->vref); 414 + 415 + return 0; 416 + } 417 + 418 + static int imx93_adc_runtime_suspend(struct device *dev) 419 + { 420 + struct iio_dev *indio_dev = dev_get_drvdata(dev); 421 + struct imx93_adc *adc = iio_priv(indio_dev); 422 + 423 + imx93_adc_power_down(adc); 424 + clk_disable_unprepare(adc->ipg_clk); 425 + regulator_disable(adc->vref); 426 + 427 + return 0; 428 + } 429 + 430 + static int imx93_adc_runtime_resume(struct device *dev) 431 + { 432 + struct iio_dev *indio_dev = dev_get_drvdata(dev); 433 + struct imx93_adc *adc = iio_priv(indio_dev); 434 + int ret; 435 + 436 + ret = regulator_enable(adc->vref); 437 + if (ret) { 438 + dev_err(dev, 439 + "Can't enable adc reference top voltage, err = %d\n", 440 + ret); 441 + return ret; 442 + } 443 + 444 + ret = clk_prepare_enable(adc->ipg_clk); 445 + if (ret) { 446 + dev_err(dev, "Could not prepare or enable clock.\n"); 447 + goto err_disable_reg; 448 + } 449 + 450 + imx93_adc_power_up(adc); 451 + 452 + return 0; 453 + 454 + err_disable_reg: 455 + regulator_disable(adc->vref); 456 + 457 + return ret; 458 + } 459 + 460 + static DEFINE_RUNTIME_DEV_PM_OPS(imx93_adc_pm_ops, 461 + imx93_adc_runtime_suspend, 462 + imx93_adc_runtime_resume, NULL); 463 + 464 + static const struct of_device_id imx93_adc_match[] = { 465 + { .compatible = "nxp,imx93-adc", }, 466 + { /* sentinel */ } 467 + }; 468 + MODULE_DEVICE_TABLE(of, imx93_adc_match); 469 + 470 + static struct platform_driver imx93_adc_driver = { 471 + .probe = imx93_adc_probe, 472 + .remove = imx93_adc_remove, 473 + .driver = { 474 + .name = IMX93_ADC_DRIVER_NAME, 475 + .of_match_table = imx93_adc_match, 476 + .pm = pm_ptr(&imx93_adc_pm_ops), 477 + }, 478 + }; 479 + 480 + module_platform_driver(imx93_adc_driver); 481 + 482 + MODULE_DESCRIPTION("NXP i.MX93 ADC driver"); 483 + MODULE_AUTHOR("Haibo Chen <haibo.chen@nxp.com>"); 484 + MODULE_LICENSE("GPL");