1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Freescale i.MX7D ADC driver 4 * 5 * Copyright (C) 2015 Freescale Semiconductor, Inc. 6 */ 7 8 #include <linux/clk.h> 9 #include <linux/completion.h> 10 #include <linux/err.h> 11 #include <linux/interrupt.h> 12 #include <linux/io.h> 13 #include <linux/kernel.h> 14 #include <linux/module.h> 15 #include <linux/platform_device.h> 16 #include <linux/regulator/consumer.h> 17 18 #include <linux/iio/iio.h> 19 #include <linux/iio/driver.h> 20 #include <linux/iio/sysfs.h> 21 22 /* ADC register */ 23 #define IMX7D_REG_ADC_CH_A_CFG1 0x00 24 #define IMX7D_REG_ADC_CH_A_CFG2 0x10 25 #define IMX7D_REG_ADC_CH_B_CFG1 0x20 26 #define IMX7D_REG_ADC_CH_B_CFG2 0x30 27 #define IMX7D_REG_ADC_CH_C_CFG1 0x40 28 #define IMX7D_REG_ADC_CH_C_CFG2 0x50 29 #define IMX7D_REG_ADC_CH_D_CFG1 0x60 30 #define IMX7D_REG_ADC_CH_D_CFG2 0x70 31 #define IMX7D_REG_ADC_CH_SW_CFG 0x80 32 #define IMX7D_REG_ADC_TIMER_UNIT 0x90 33 #define IMX7D_REG_ADC_DMA_FIFO 0xa0 34 #define IMX7D_REG_ADC_FIFO_STATUS 0xb0 35 #define IMX7D_REG_ADC_INT_SIG_EN 0xc0 36 #define IMX7D_REG_ADC_INT_EN 0xd0 37 #define IMX7D_REG_ADC_INT_STATUS 0xe0 38 #define IMX7D_REG_ADC_CHA_B_CNV_RSLT 0xf0 39 #define IMX7D_REG_ADC_CHC_D_CNV_RSLT 0x100 40 #define IMX7D_REG_ADC_CH_SW_CNV_RSLT 0x110 41 #define IMX7D_REG_ADC_DMA_FIFO_DAT 0x120 42 #define IMX7D_REG_ADC_ADC_CFG 0x130 43 44 #define IMX7D_REG_ADC_CHANNEL_CFG2_BASE 0x10 45 #define IMX7D_EACH_CHANNEL_REG_OFFSET 0x20 46 47 #define IMX7D_REG_ADC_CH_CFG1_CHANNEL_EN (0x1 << 31) 48 #define IMX7D_REG_ADC_CH_CFG1_CHANNEL_SINGLE BIT(30) 49 #define IMX7D_REG_ADC_CH_CFG1_CHANNEL_AVG_EN BIT(29) 50 #define IMX7D_REG_ADC_CH_CFG1_CHANNEL_SEL(x) ((x) << 24) 51 52 #define IMX7D_REG_ADC_CH_CFG2_AVG_NUM_4 (0x0 << 12) 53 #define IMX7D_REG_ADC_CH_CFG2_AVG_NUM_8 (0x1 << 12) 54 #define IMX7D_REG_ADC_CH_CFG2_AVG_NUM_16 (0x2 << 12) 55 #define IMX7D_REG_ADC_CH_CFG2_AVG_NUM_32 (0x3 << 12) 56 57 #define IMX7D_REG_ADC_TIMER_UNIT_PRE_DIV_4 (0x0 << 29) 58 #define IMX7D_REG_ADC_TIMER_UNIT_PRE_DIV_8 (0x1 << 29) 59 #define IMX7D_REG_ADC_TIMER_UNIT_PRE_DIV_16 (0x2 << 29) 60 #define IMX7D_REG_ADC_TIMER_UNIT_PRE_DIV_32 (0x3 << 29) 61 #define IMX7D_REG_ADC_TIMER_UNIT_PRE_DIV_64 (0x4 << 29) 62 #define IMX7D_REG_ADC_TIMER_UNIT_PRE_DIV_128 (0x5 << 29) 63 64 #define IMX7D_REG_ADC_ADC_CFG_ADC_CLK_DOWN BIT(31) 65 #define IMX7D_REG_ADC_ADC_CFG_ADC_POWER_DOWN BIT(1) 66 #define IMX7D_REG_ADC_ADC_CFG_ADC_EN BIT(0) 67 68 #define IMX7D_REG_ADC_INT_CHA_COV_INT_EN BIT(8) 69 #define IMX7D_REG_ADC_INT_CHB_COV_INT_EN BIT(9) 70 #define IMX7D_REG_ADC_INT_CHC_COV_INT_EN BIT(10) 71 #define IMX7D_REG_ADC_INT_CHD_COV_INT_EN BIT(11) 72 #define IMX7D_REG_ADC_INT_CHANNEL_INT_EN \ 73 (IMX7D_REG_ADC_INT_CHA_COV_INT_EN | \ 74 IMX7D_REG_ADC_INT_CHB_COV_INT_EN | \ 75 IMX7D_REG_ADC_INT_CHC_COV_INT_EN | \ 76 IMX7D_REG_ADC_INT_CHD_COV_INT_EN) 77 #define IMX7D_REG_ADC_INT_STATUS_CHANNEL_INT_STATUS 0xf00 78 #define IMX7D_REG_ADC_INT_STATUS_CHANNEL_CONV_TIME_OUT 0xf0000 79 80 #define IMX7D_ADC_TIMEOUT msecs_to_jiffies(100) 81 82 enum imx7d_adc_clk_pre_div { 83 IMX7D_ADC_ANALOG_CLK_PRE_DIV_4, 84 IMX7D_ADC_ANALOG_CLK_PRE_DIV_8, 85 IMX7D_ADC_ANALOG_CLK_PRE_DIV_16, 86 IMX7D_ADC_ANALOG_CLK_PRE_DIV_32, 87 IMX7D_ADC_ANALOG_CLK_PRE_DIV_64, 88 IMX7D_ADC_ANALOG_CLK_PRE_DIV_128, 89 }; 90 91 enum imx7d_adc_average_num { 92 IMX7D_ADC_AVERAGE_NUM_4, 93 IMX7D_ADC_AVERAGE_NUM_8, 94 IMX7D_ADC_AVERAGE_NUM_16, 95 IMX7D_ADC_AVERAGE_NUM_32, 96 }; 97 98 struct imx7d_adc_feature { 99 enum imx7d_adc_clk_pre_div clk_pre_div; 100 enum imx7d_adc_average_num avg_num; 101 102 u32 core_time_unit; /* impact the sample rate */ 103 104 bool average_en; 105 }; 106 107 struct imx7d_adc { 108 struct device *dev; 109 void __iomem *regs; 110 struct clk *clk; 111 112 u32 vref_uv; 113 u32 value; 114 u32 channel; 115 u32 pre_div_num; 116 117 struct regulator *vref; 118 struct imx7d_adc_feature adc_feature; 119 120 struct completion completion; 121 }; 122 123 struct imx7d_adc_analogue_core_clk { 124 u32 pre_div; 125 u32 reg_config; 126 }; 127 128 #define IMX7D_ADC_ANALOGUE_CLK_CONFIG(_pre_div, _reg_conf) { \ 129 .pre_div = (_pre_div), \ 130 .reg_config = (_reg_conf), \ 131 } 132 133 static const struct imx7d_adc_analogue_core_clk imx7d_adc_analogue_clk[] = { 134 IMX7D_ADC_ANALOGUE_CLK_CONFIG(4, IMX7D_REG_ADC_TIMER_UNIT_PRE_DIV_4), 135 IMX7D_ADC_ANALOGUE_CLK_CONFIG(8, IMX7D_REG_ADC_TIMER_UNIT_PRE_DIV_8), 136 IMX7D_ADC_ANALOGUE_CLK_CONFIG(16, IMX7D_REG_ADC_TIMER_UNIT_PRE_DIV_16), 137 IMX7D_ADC_ANALOGUE_CLK_CONFIG(32, IMX7D_REG_ADC_TIMER_UNIT_PRE_DIV_32), 138 IMX7D_ADC_ANALOGUE_CLK_CONFIG(64, IMX7D_REG_ADC_TIMER_UNIT_PRE_DIV_64), 139 IMX7D_ADC_ANALOGUE_CLK_CONFIG(128, IMX7D_REG_ADC_TIMER_UNIT_PRE_DIV_128), 140 }; 141 142 #define IMX7D_ADC_CHAN(_idx) { \ 143 .type = IIO_VOLTAGE, \ 144 .indexed = 1, \ 145 .channel = (_idx), \ 146 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ 147 .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | \ 148 BIT(IIO_CHAN_INFO_SAMP_FREQ), \ 149 } 150 151 static const struct iio_chan_spec imx7d_adc_iio_channels[] = { 152 IMX7D_ADC_CHAN(0), 153 IMX7D_ADC_CHAN(1), 154 IMX7D_ADC_CHAN(2), 155 IMX7D_ADC_CHAN(3), 156 IMX7D_ADC_CHAN(4), 157 IMX7D_ADC_CHAN(5), 158 IMX7D_ADC_CHAN(6), 159 IMX7D_ADC_CHAN(7), 160 IMX7D_ADC_CHAN(8), 161 IMX7D_ADC_CHAN(9), 162 IMX7D_ADC_CHAN(10), 163 IMX7D_ADC_CHAN(11), 164 IMX7D_ADC_CHAN(12), 165 IMX7D_ADC_CHAN(13), 166 IMX7D_ADC_CHAN(14), 167 IMX7D_ADC_CHAN(15), 168 }; 169 170 static const u32 imx7d_adc_average_num[] = { 171 IMX7D_REG_ADC_CH_CFG2_AVG_NUM_4, 172 IMX7D_REG_ADC_CH_CFG2_AVG_NUM_8, 173 IMX7D_REG_ADC_CH_CFG2_AVG_NUM_16, 174 IMX7D_REG_ADC_CH_CFG2_AVG_NUM_32, 175 }; 176 177 static void imx7d_adc_feature_config(struct imx7d_adc *info) 178 { 179 info->adc_feature.clk_pre_div = IMX7D_ADC_ANALOG_CLK_PRE_DIV_4; 180 info->adc_feature.avg_num = IMX7D_ADC_AVERAGE_NUM_32; 181 info->adc_feature.core_time_unit = 1; 182 info->adc_feature.average_en = true; 183 } 184 185 static void imx7d_adc_sample_rate_set(struct imx7d_adc *info) 186 { 187 struct imx7d_adc_feature *adc_feature = &info->adc_feature; 188 struct imx7d_adc_analogue_core_clk adc_analogure_clk; 189 u32 i; 190 u32 tmp_cfg1; 191 u32 sample_rate = 0; 192 193 /* 194 * Before sample set, disable channel A,B,C,D. Here we 195 * clear the bit 31 of register REG_ADC_CH_A\B\C\D_CFG1. 196 */ 197 for (i = 0; i < 4; i++) { 198 tmp_cfg1 = 199 readl(info->regs + i * IMX7D_EACH_CHANNEL_REG_OFFSET); 200 tmp_cfg1 &= ~IMX7D_REG_ADC_CH_CFG1_CHANNEL_EN; 201 writel(tmp_cfg1, 202 info->regs + i * IMX7D_EACH_CHANNEL_REG_OFFSET); 203 } 204 205 adc_analogure_clk = imx7d_adc_analogue_clk[adc_feature->clk_pre_div]; 206 sample_rate |= adc_analogure_clk.reg_config; 207 info->pre_div_num = adc_analogure_clk.pre_div; 208 209 sample_rate |= adc_feature->core_time_unit; 210 writel(sample_rate, info->regs + IMX7D_REG_ADC_TIMER_UNIT); 211 } 212 213 static void imx7d_adc_hw_init(struct imx7d_adc *info) 214 { 215 u32 cfg; 216 217 /* power up and enable adc analogue core */ 218 cfg = readl(info->regs + IMX7D_REG_ADC_ADC_CFG); 219 cfg &= ~(IMX7D_REG_ADC_ADC_CFG_ADC_CLK_DOWN | 220 IMX7D_REG_ADC_ADC_CFG_ADC_POWER_DOWN); 221 cfg |= IMX7D_REG_ADC_ADC_CFG_ADC_EN; 222 writel(cfg, info->regs + IMX7D_REG_ADC_ADC_CFG); 223 224 /* enable channel A,B,C,D interrupt */ 225 writel(IMX7D_REG_ADC_INT_CHANNEL_INT_EN, 226 info->regs + IMX7D_REG_ADC_INT_SIG_EN); 227 writel(IMX7D_REG_ADC_INT_CHANNEL_INT_EN, 228 info->regs + IMX7D_REG_ADC_INT_EN); 229 230 imx7d_adc_sample_rate_set(info); 231 } 232 233 static void imx7d_adc_channel_set(struct imx7d_adc *info) 234 { 235 u32 cfg1 = 0; 236 u32 cfg2; 237 u32 channel; 238 239 channel = info->channel; 240 241 /* the channel choose single conversion, and enable average mode */ 242 cfg1 |= (IMX7D_REG_ADC_CH_CFG1_CHANNEL_EN | 243 IMX7D_REG_ADC_CH_CFG1_CHANNEL_SINGLE); 244 if (info->adc_feature.average_en) 245 cfg1 |= IMX7D_REG_ADC_CH_CFG1_CHANNEL_AVG_EN; 246 247 /* 248 * physical channel 0 chose logical channel A 249 * physical channel 1 chose logical channel B 250 * physical channel 2 chose logical channel C 251 * physical channel 3 chose logical channel D 252 */ 253 cfg1 |= IMX7D_REG_ADC_CH_CFG1_CHANNEL_SEL(channel); 254 255 /* 256 * read register REG_ADC_CH_A\B\C\D_CFG2, according to the 257 * channel chosen 258 */ 259 cfg2 = readl(info->regs + IMX7D_EACH_CHANNEL_REG_OFFSET * channel + 260 IMX7D_REG_ADC_CHANNEL_CFG2_BASE); 261 262 cfg2 |= imx7d_adc_average_num[info->adc_feature.avg_num]; 263 264 /* 265 * write the register REG_ADC_CH_A\B\C\D_CFG2, according to 266 * the channel chosen 267 */ 268 writel(cfg2, info->regs + IMX7D_EACH_CHANNEL_REG_OFFSET * channel + 269 IMX7D_REG_ADC_CHANNEL_CFG2_BASE); 270 writel(cfg1, info->regs + IMX7D_EACH_CHANNEL_REG_OFFSET * channel); 271 } 272 273 static u32 imx7d_adc_get_sample_rate(struct imx7d_adc *info) 274 { 275 /* input clock is always 24MHz */ 276 u32 input_clk = 24000000; 277 u32 analogue_core_clk; 278 u32 core_time_unit = info->adc_feature.core_time_unit; 279 u32 tmp; 280 281 analogue_core_clk = input_clk / info->pre_div_num; 282 tmp = (core_time_unit + 1) * 6; 283 284 return analogue_core_clk / tmp; 285 } 286 287 static int imx7d_adc_read_raw(struct iio_dev *indio_dev, 288 struct iio_chan_spec const *chan, 289 int *val, 290 int *val2, 291 long mask) 292 { 293 struct imx7d_adc *info = iio_priv(indio_dev); 294 295 u32 channel; 296 long ret; 297 298 switch (mask) { 299 case IIO_CHAN_INFO_RAW: 300 mutex_lock(&indio_dev->mlock); 301 reinit_completion(&info->completion); 302 303 channel = chan->channel & 0x03; 304 info->channel = channel; 305 imx7d_adc_channel_set(info); 306 307 ret = wait_for_completion_interruptible_timeout 308 (&info->completion, IMX7D_ADC_TIMEOUT); 309 if (ret == 0) { 310 mutex_unlock(&indio_dev->mlock); 311 return -ETIMEDOUT; 312 } 313 if (ret < 0) { 314 mutex_unlock(&indio_dev->mlock); 315 return ret; 316 } 317 318 *val = info->value; 319 mutex_unlock(&indio_dev->mlock); 320 return IIO_VAL_INT; 321 322 case IIO_CHAN_INFO_SCALE: 323 info->vref_uv = regulator_get_voltage(info->vref); 324 *val = info->vref_uv / 1000; 325 *val2 = 12; 326 return IIO_VAL_FRACTIONAL_LOG2; 327 328 case IIO_CHAN_INFO_SAMP_FREQ: 329 *val = imx7d_adc_get_sample_rate(info); 330 return IIO_VAL_INT; 331 332 default: 333 return -EINVAL; 334 } 335 } 336 337 static int imx7d_adc_read_data(struct imx7d_adc *info) 338 { 339 u32 channel; 340 u32 value; 341 342 channel = info->channel & 0x03; 343 344 /* 345 * channel A and B conversion result share one register, 346 * bit[27~16] is the channel B conversion result, 347 * bit[11~0] is the channel A conversion result. 348 * channel C and D is the same. 349 */ 350 if (channel < 2) 351 value = readl(info->regs + IMX7D_REG_ADC_CHA_B_CNV_RSLT); 352 else 353 value = readl(info->regs + IMX7D_REG_ADC_CHC_D_CNV_RSLT); 354 if (channel & 0x1) /* channel B or D */ 355 value = (value >> 16) & 0xFFF; 356 else /* channel A or C */ 357 value &= 0xFFF; 358 359 return value; 360 } 361 362 static irqreturn_t imx7d_adc_isr(int irq, void *dev_id) 363 { 364 struct imx7d_adc *info = dev_id; 365 int status; 366 367 status = readl(info->regs + IMX7D_REG_ADC_INT_STATUS); 368 if (status & IMX7D_REG_ADC_INT_STATUS_CHANNEL_INT_STATUS) { 369 info->value = imx7d_adc_read_data(info); 370 complete(&info->completion); 371 372 /* 373 * The register IMX7D_REG_ADC_INT_STATUS can't clear 374 * itself after read operation, need software to write 375 * 0 to the related bit. Here we clear the channel A/B/C/D 376 * conversion finished flag. 377 */ 378 status &= ~IMX7D_REG_ADC_INT_STATUS_CHANNEL_INT_STATUS; 379 writel(status, info->regs + IMX7D_REG_ADC_INT_STATUS); 380 } 381 382 /* 383 * If the channel A/B/C/D conversion timeout, report it and clear these 384 * timeout flags. 385 */ 386 if (status & IMX7D_REG_ADC_INT_STATUS_CHANNEL_CONV_TIME_OUT) { 387 dev_err(info->dev, 388 "ADC got conversion time out interrupt: 0x%08x\n", 389 status); 390 status &= ~IMX7D_REG_ADC_INT_STATUS_CHANNEL_CONV_TIME_OUT; 391 writel(status, info->regs + IMX7D_REG_ADC_INT_STATUS); 392 } 393 394 return IRQ_HANDLED; 395 } 396 397 static int imx7d_adc_reg_access(struct iio_dev *indio_dev, 398 unsigned reg, unsigned writeval, 399 unsigned *readval) 400 { 401 struct imx7d_adc *info = iio_priv(indio_dev); 402 403 if (!readval || reg % 4 || reg > IMX7D_REG_ADC_ADC_CFG) 404 return -EINVAL; 405 406 *readval = readl(info->regs + reg); 407 408 return 0; 409 } 410 411 static const struct iio_info imx7d_adc_iio_info = { 412 .read_raw = &imx7d_adc_read_raw, 413 .debugfs_reg_access = &imx7d_adc_reg_access, 414 }; 415 416 static const struct of_device_id imx7d_adc_match[] = { 417 { .compatible = "fsl,imx7d-adc", }, 418 { /* sentinel */ } 419 }; 420 MODULE_DEVICE_TABLE(of, imx7d_adc_match); 421 422 static void imx7d_adc_power_down(struct imx7d_adc *info) 423 { 424 u32 adc_cfg; 425 426 adc_cfg = readl(info->regs + IMX7D_REG_ADC_ADC_CFG); 427 adc_cfg |= IMX7D_REG_ADC_ADC_CFG_ADC_CLK_DOWN | 428 IMX7D_REG_ADC_ADC_CFG_ADC_POWER_DOWN; 429 adc_cfg &= ~IMX7D_REG_ADC_ADC_CFG_ADC_EN; 430 writel(adc_cfg, info->regs + IMX7D_REG_ADC_ADC_CFG); 431 } 432 433 static int imx7d_adc_enable(struct device *dev) 434 { 435 struct iio_dev *indio_dev = dev_get_drvdata(dev); 436 struct imx7d_adc *info = iio_priv(indio_dev); 437 int ret; 438 439 ret = regulator_enable(info->vref); 440 if (ret) { 441 dev_err(info->dev, 442 "Can't enable adc reference top voltage, err = %d\n", 443 ret); 444 return ret; 445 } 446 447 ret = clk_prepare_enable(info->clk); 448 if (ret) { 449 dev_err(info->dev, 450 "Could not prepare or enable clock.\n"); 451 regulator_disable(info->vref); 452 return ret; 453 } 454 455 imx7d_adc_hw_init(info); 456 457 return 0; 458 } 459 460 static int imx7d_adc_disable(struct device *dev) 461 { 462 struct iio_dev *indio_dev = dev_get_drvdata(dev); 463 struct imx7d_adc *info = iio_priv(indio_dev); 464 465 imx7d_adc_power_down(info); 466 467 clk_disable_unprepare(info->clk); 468 regulator_disable(info->vref); 469 470 return 0; 471 } 472 473 static void __imx7d_adc_disable(void *data) 474 { 475 imx7d_adc_disable(data); 476 } 477 478 static int imx7d_adc_probe(struct platform_device *pdev) 479 { 480 struct imx7d_adc *info; 481 struct iio_dev *indio_dev; 482 struct device *dev = &pdev->dev; 483 int irq; 484 int ret; 485 486 indio_dev = devm_iio_device_alloc(dev, sizeof(*info)); 487 if (!indio_dev) { 488 dev_err(&pdev->dev, "Failed allocating iio device\n"); 489 return -ENOMEM; 490 } 491 492 info = iio_priv(indio_dev); 493 info->dev = dev; 494 495 info->regs = devm_platform_ioremap_resource(pdev, 0); 496 if (IS_ERR(info->regs)) { 497 ret = PTR_ERR(info->regs); 498 dev_err(dev, "Failed to remap adc memory, err = %d\n", ret); 499 return ret; 500 } 501 502 irq = platform_get_irq(pdev, 0); 503 if (irq < 0) { 504 dev_err(dev, "No irq resource?\n"); 505 return irq; 506 } 507 508 info->clk = devm_clk_get(dev, "adc"); 509 if (IS_ERR(info->clk)) { 510 ret = PTR_ERR(info->clk); 511 dev_err(dev, "Failed getting clock, err = %d\n", ret); 512 return ret; 513 } 514 515 info->vref = devm_regulator_get(dev, "vref"); 516 if (IS_ERR(info->vref)) { 517 ret = PTR_ERR(info->vref); 518 dev_err(dev, 519 "Failed getting reference voltage, err = %d\n", ret); 520 return ret; 521 } 522 523 platform_set_drvdata(pdev, indio_dev); 524 525 init_completion(&info->completion); 526 527 indio_dev->name = dev_name(dev); 528 indio_dev->dev.parent = dev; 529 indio_dev->info = &imx7d_adc_iio_info; 530 indio_dev->modes = INDIO_DIRECT_MODE; 531 indio_dev->channels = imx7d_adc_iio_channels; 532 indio_dev->num_channels = ARRAY_SIZE(imx7d_adc_iio_channels); 533 534 ret = devm_request_irq(dev, irq, 535 imx7d_adc_isr, 0, 536 dev_name(dev), info); 537 if (ret < 0) { 538 dev_err(dev, "Failed requesting irq, irq = %d\n", irq); 539 return ret; 540 } 541 542 imx7d_adc_feature_config(info); 543 544 ret = imx7d_adc_enable(&indio_dev->dev); 545 if (ret) 546 return ret; 547 548 ret = devm_add_action_or_reset(dev, __imx7d_adc_disable, 549 &indio_dev->dev); 550 if (ret) 551 return ret; 552 553 ret = devm_iio_device_register(dev, indio_dev); 554 if (ret) { 555 dev_err(&pdev->dev, "Couldn't register the device.\n"); 556 return ret; 557 } 558 559 return 0; 560 } 561 562 static SIMPLE_DEV_PM_OPS(imx7d_adc_pm_ops, imx7d_adc_disable, imx7d_adc_enable); 563 564 static struct platform_driver imx7d_adc_driver = { 565 .probe = imx7d_adc_probe, 566 .driver = { 567 .name = "imx7d_adc", 568 .of_match_table = imx7d_adc_match, 569 .pm = &imx7d_adc_pm_ops, 570 }, 571 }; 572 573 module_platform_driver(imx7d_adc_driver); 574 575 MODULE_AUTHOR("Haibo Chen <haibo.chen@freescale.com>"); 576 MODULE_DESCRIPTION("Freescale IMX7D ADC driver"); 577 MODULE_LICENSE("GPL v2"); 578