1*9bf85fbcSTomer Maimon // SPDX-License-Identifier: GPL-2.0 2*9bf85fbcSTomer Maimon // Copyright (c) 2019 Nuvoton Technology corporation. 3*9bf85fbcSTomer Maimon 4*9bf85fbcSTomer Maimon #include <linux/clk.h> 5*9bf85fbcSTomer Maimon #include <linux/device.h> 6*9bf85fbcSTomer Maimon #include <linux/mfd/syscon.h> 7*9bf85fbcSTomer Maimon #include <linux/io.h> 8*9bf85fbcSTomer Maimon #include <linux/iio/iio.h> 9*9bf85fbcSTomer Maimon #include <linux/interrupt.h> 10*9bf85fbcSTomer Maimon #include <linux/kernel.h> 11*9bf85fbcSTomer Maimon #include <linux/module.h> 12*9bf85fbcSTomer Maimon #include <linux/platform_device.h> 13*9bf85fbcSTomer Maimon #include <linux/regmap.h> 14*9bf85fbcSTomer Maimon #include <linux/regulator/consumer.h> 15*9bf85fbcSTomer Maimon #include <linux/spinlock.h> 16*9bf85fbcSTomer Maimon #include <linux/uaccess.h> 17*9bf85fbcSTomer Maimon 18*9bf85fbcSTomer Maimon struct npcm_adc { 19*9bf85fbcSTomer Maimon bool int_status; 20*9bf85fbcSTomer Maimon u32 adc_sample_hz; 21*9bf85fbcSTomer Maimon struct device *dev; 22*9bf85fbcSTomer Maimon void __iomem *regs; 23*9bf85fbcSTomer Maimon struct clk *adc_clk; 24*9bf85fbcSTomer Maimon wait_queue_head_t wq; 25*9bf85fbcSTomer Maimon struct regulator *vref; 26*9bf85fbcSTomer Maimon struct regmap *rst_regmap; 27*9bf85fbcSTomer Maimon }; 28*9bf85fbcSTomer Maimon 29*9bf85fbcSTomer Maimon /* NPCM7xx reset module */ 30*9bf85fbcSTomer Maimon #define NPCM7XX_IPSRST1_OFFSET 0x020 31*9bf85fbcSTomer Maimon #define NPCM7XX_IPSRST1_ADC_RST BIT(27) 32*9bf85fbcSTomer Maimon 33*9bf85fbcSTomer Maimon /* ADC registers */ 34*9bf85fbcSTomer Maimon #define NPCM_ADCCON 0x00 35*9bf85fbcSTomer Maimon #define NPCM_ADCDATA 0x04 36*9bf85fbcSTomer Maimon 37*9bf85fbcSTomer Maimon /* ADCCON Register Bits */ 38*9bf85fbcSTomer Maimon #define NPCM_ADCCON_ADC_INT_EN BIT(21) 39*9bf85fbcSTomer Maimon #define NPCM_ADCCON_REFSEL BIT(19) 40*9bf85fbcSTomer Maimon #define NPCM_ADCCON_ADC_INT_ST BIT(18) 41*9bf85fbcSTomer Maimon #define NPCM_ADCCON_ADC_EN BIT(17) 42*9bf85fbcSTomer Maimon #define NPCM_ADCCON_ADC_RST BIT(16) 43*9bf85fbcSTomer Maimon #define NPCM_ADCCON_ADC_CONV BIT(13) 44*9bf85fbcSTomer Maimon 45*9bf85fbcSTomer Maimon #define NPCM_ADCCON_CH_MASK GENMASK(27, 24) 46*9bf85fbcSTomer Maimon #define NPCM_ADCCON_CH(x) ((x) << 24) 47*9bf85fbcSTomer Maimon #define NPCM_ADCCON_DIV_SHIFT 1 48*9bf85fbcSTomer Maimon #define NPCM_ADCCON_DIV_MASK GENMASK(8, 1) 49*9bf85fbcSTomer Maimon #define NPCM_ADC_DATA_MASK(x) ((x) & GENMASK(9, 0)) 50*9bf85fbcSTomer Maimon 51*9bf85fbcSTomer Maimon #define NPCM_ADC_ENABLE (NPCM_ADCCON_ADC_EN | NPCM_ADCCON_ADC_INT_EN) 52*9bf85fbcSTomer Maimon 53*9bf85fbcSTomer Maimon /* ADC General Definition */ 54*9bf85fbcSTomer Maimon #define NPCM_RESOLUTION_BITS 10 55*9bf85fbcSTomer Maimon #define NPCM_INT_VREF_MV 2000 56*9bf85fbcSTomer Maimon 57*9bf85fbcSTomer Maimon #define NPCM_ADC_CHAN(ch) { \ 58*9bf85fbcSTomer Maimon .type = IIO_VOLTAGE, \ 59*9bf85fbcSTomer Maimon .indexed = 1, \ 60*9bf85fbcSTomer Maimon .channel = ch, \ 61*9bf85fbcSTomer Maimon .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ 62*9bf85fbcSTomer Maimon .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | \ 63*9bf85fbcSTomer Maimon BIT(IIO_CHAN_INFO_SAMP_FREQ), \ 64*9bf85fbcSTomer Maimon } 65*9bf85fbcSTomer Maimon 66*9bf85fbcSTomer Maimon static const struct iio_chan_spec npcm_adc_iio_channels[] = { 67*9bf85fbcSTomer Maimon NPCM_ADC_CHAN(0), 68*9bf85fbcSTomer Maimon NPCM_ADC_CHAN(1), 69*9bf85fbcSTomer Maimon NPCM_ADC_CHAN(2), 70*9bf85fbcSTomer Maimon NPCM_ADC_CHAN(3), 71*9bf85fbcSTomer Maimon NPCM_ADC_CHAN(4), 72*9bf85fbcSTomer Maimon NPCM_ADC_CHAN(5), 73*9bf85fbcSTomer Maimon NPCM_ADC_CHAN(6), 74*9bf85fbcSTomer Maimon NPCM_ADC_CHAN(7), 75*9bf85fbcSTomer Maimon }; 76*9bf85fbcSTomer Maimon 77*9bf85fbcSTomer Maimon static irqreturn_t npcm_adc_isr(int irq, void *data) 78*9bf85fbcSTomer Maimon { 79*9bf85fbcSTomer Maimon u32 regtemp; 80*9bf85fbcSTomer Maimon struct iio_dev *indio_dev = data; 81*9bf85fbcSTomer Maimon struct npcm_adc *info = iio_priv(indio_dev); 82*9bf85fbcSTomer Maimon 83*9bf85fbcSTomer Maimon regtemp = ioread32(info->regs + NPCM_ADCCON); 84*9bf85fbcSTomer Maimon if (regtemp & NPCM_ADCCON_ADC_INT_ST) { 85*9bf85fbcSTomer Maimon iowrite32(regtemp, info->regs + NPCM_ADCCON); 86*9bf85fbcSTomer Maimon wake_up_interruptible(&info->wq); 87*9bf85fbcSTomer Maimon info->int_status = true; 88*9bf85fbcSTomer Maimon } 89*9bf85fbcSTomer Maimon 90*9bf85fbcSTomer Maimon return IRQ_HANDLED; 91*9bf85fbcSTomer Maimon } 92*9bf85fbcSTomer Maimon 93*9bf85fbcSTomer Maimon static int npcm_adc_read(struct npcm_adc *info, int *val, u8 channel) 94*9bf85fbcSTomer Maimon { 95*9bf85fbcSTomer Maimon int ret; 96*9bf85fbcSTomer Maimon u32 regtemp; 97*9bf85fbcSTomer Maimon 98*9bf85fbcSTomer Maimon /* Select ADC channel */ 99*9bf85fbcSTomer Maimon regtemp = ioread32(info->regs + NPCM_ADCCON); 100*9bf85fbcSTomer Maimon regtemp &= ~NPCM_ADCCON_CH_MASK; 101*9bf85fbcSTomer Maimon info->int_status = false; 102*9bf85fbcSTomer Maimon iowrite32(regtemp | NPCM_ADCCON_CH(channel) | 103*9bf85fbcSTomer Maimon NPCM_ADCCON_ADC_CONV, info->regs + NPCM_ADCCON); 104*9bf85fbcSTomer Maimon 105*9bf85fbcSTomer Maimon ret = wait_event_interruptible_timeout(info->wq, info->int_status, 106*9bf85fbcSTomer Maimon msecs_to_jiffies(10)); 107*9bf85fbcSTomer Maimon if (ret == 0) { 108*9bf85fbcSTomer Maimon regtemp = ioread32(info->regs + NPCM_ADCCON); 109*9bf85fbcSTomer Maimon if ((regtemp & NPCM_ADCCON_ADC_CONV) && info->rst_regmap) { 110*9bf85fbcSTomer Maimon /* if conversion failed - reset ADC module */ 111*9bf85fbcSTomer Maimon regmap_write(info->rst_regmap, NPCM7XX_IPSRST1_OFFSET, 112*9bf85fbcSTomer Maimon NPCM7XX_IPSRST1_ADC_RST); 113*9bf85fbcSTomer Maimon msleep(100); 114*9bf85fbcSTomer Maimon regmap_write(info->rst_regmap, NPCM7XX_IPSRST1_OFFSET, 115*9bf85fbcSTomer Maimon 0x0); 116*9bf85fbcSTomer Maimon msleep(100); 117*9bf85fbcSTomer Maimon 118*9bf85fbcSTomer Maimon /* Enable ADC and start conversion module */ 119*9bf85fbcSTomer Maimon iowrite32(NPCM_ADC_ENABLE | NPCM_ADCCON_ADC_CONV, 120*9bf85fbcSTomer Maimon info->regs + NPCM_ADCCON); 121*9bf85fbcSTomer Maimon dev_err(info->dev, "RESET ADC Complete\n"); 122*9bf85fbcSTomer Maimon } 123*9bf85fbcSTomer Maimon return -ETIMEDOUT; 124*9bf85fbcSTomer Maimon } 125*9bf85fbcSTomer Maimon if (ret < 0) 126*9bf85fbcSTomer Maimon return ret; 127*9bf85fbcSTomer Maimon 128*9bf85fbcSTomer Maimon *val = NPCM_ADC_DATA_MASK(ioread32(info->regs + NPCM_ADCDATA)); 129*9bf85fbcSTomer Maimon 130*9bf85fbcSTomer Maimon return 0; 131*9bf85fbcSTomer Maimon } 132*9bf85fbcSTomer Maimon 133*9bf85fbcSTomer Maimon static int npcm_adc_read_raw(struct iio_dev *indio_dev, 134*9bf85fbcSTomer Maimon struct iio_chan_spec const *chan, int *val, 135*9bf85fbcSTomer Maimon int *val2, long mask) 136*9bf85fbcSTomer Maimon { 137*9bf85fbcSTomer Maimon int ret; 138*9bf85fbcSTomer Maimon int vref_uv; 139*9bf85fbcSTomer Maimon struct npcm_adc *info = iio_priv(indio_dev); 140*9bf85fbcSTomer Maimon 141*9bf85fbcSTomer Maimon switch (mask) { 142*9bf85fbcSTomer Maimon case IIO_CHAN_INFO_RAW: 143*9bf85fbcSTomer Maimon mutex_lock(&indio_dev->mlock); 144*9bf85fbcSTomer Maimon ret = npcm_adc_read(info, val, chan->channel); 145*9bf85fbcSTomer Maimon mutex_unlock(&indio_dev->mlock); 146*9bf85fbcSTomer Maimon if (ret) { 147*9bf85fbcSTomer Maimon dev_err(info->dev, "NPCM ADC read failed\n"); 148*9bf85fbcSTomer Maimon return ret; 149*9bf85fbcSTomer Maimon } 150*9bf85fbcSTomer Maimon return IIO_VAL_INT; 151*9bf85fbcSTomer Maimon case IIO_CHAN_INFO_SCALE: 152*9bf85fbcSTomer Maimon if (info->vref) { 153*9bf85fbcSTomer Maimon vref_uv = regulator_get_voltage(info->vref); 154*9bf85fbcSTomer Maimon *val = vref_uv / 1000; 155*9bf85fbcSTomer Maimon } else { 156*9bf85fbcSTomer Maimon *val = NPCM_INT_VREF_MV; 157*9bf85fbcSTomer Maimon } 158*9bf85fbcSTomer Maimon *val2 = NPCM_RESOLUTION_BITS; 159*9bf85fbcSTomer Maimon return IIO_VAL_FRACTIONAL_LOG2; 160*9bf85fbcSTomer Maimon case IIO_CHAN_INFO_SAMP_FREQ: 161*9bf85fbcSTomer Maimon *val = info->adc_sample_hz; 162*9bf85fbcSTomer Maimon return IIO_VAL_INT; 163*9bf85fbcSTomer Maimon default: 164*9bf85fbcSTomer Maimon return -EINVAL; 165*9bf85fbcSTomer Maimon } 166*9bf85fbcSTomer Maimon 167*9bf85fbcSTomer Maimon return 0; 168*9bf85fbcSTomer Maimon } 169*9bf85fbcSTomer Maimon 170*9bf85fbcSTomer Maimon static const struct iio_info npcm_adc_iio_info = { 171*9bf85fbcSTomer Maimon .read_raw = &npcm_adc_read_raw, 172*9bf85fbcSTomer Maimon }; 173*9bf85fbcSTomer Maimon 174*9bf85fbcSTomer Maimon static const struct of_device_id npcm_adc_match[] = { 175*9bf85fbcSTomer Maimon { .compatible = "nuvoton,npcm750-adc", }, 176*9bf85fbcSTomer Maimon { /* sentinel */ } 177*9bf85fbcSTomer Maimon }; 178*9bf85fbcSTomer Maimon MODULE_DEVICE_TABLE(of, npcm_adc_match); 179*9bf85fbcSTomer Maimon 180*9bf85fbcSTomer Maimon static int npcm_adc_probe(struct platform_device *pdev) 181*9bf85fbcSTomer Maimon { 182*9bf85fbcSTomer Maimon int ret; 183*9bf85fbcSTomer Maimon int irq; 184*9bf85fbcSTomer Maimon u32 div; 185*9bf85fbcSTomer Maimon u32 reg_con; 186*9bf85fbcSTomer Maimon struct resource *res; 187*9bf85fbcSTomer Maimon struct npcm_adc *info; 188*9bf85fbcSTomer Maimon struct iio_dev *indio_dev; 189*9bf85fbcSTomer Maimon struct device *dev = &pdev->dev; 190*9bf85fbcSTomer Maimon struct device_node *np = pdev->dev.of_node; 191*9bf85fbcSTomer Maimon 192*9bf85fbcSTomer Maimon indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*info)); 193*9bf85fbcSTomer Maimon if (!indio_dev) 194*9bf85fbcSTomer Maimon return -ENOMEM; 195*9bf85fbcSTomer Maimon info = iio_priv(indio_dev); 196*9bf85fbcSTomer Maimon 197*9bf85fbcSTomer Maimon info->dev = &pdev->dev; 198*9bf85fbcSTomer Maimon 199*9bf85fbcSTomer Maimon res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 200*9bf85fbcSTomer Maimon info->regs = devm_ioremap_resource(&pdev->dev, res); 201*9bf85fbcSTomer Maimon if (IS_ERR(info->regs)) 202*9bf85fbcSTomer Maimon return PTR_ERR(info->regs); 203*9bf85fbcSTomer Maimon 204*9bf85fbcSTomer Maimon info->adc_clk = devm_clk_get(&pdev->dev, NULL); 205*9bf85fbcSTomer Maimon if (IS_ERR(info->adc_clk)) { 206*9bf85fbcSTomer Maimon dev_warn(&pdev->dev, "ADC clock failed: can't read clk\n"); 207*9bf85fbcSTomer Maimon return PTR_ERR(info->adc_clk); 208*9bf85fbcSTomer Maimon } 209*9bf85fbcSTomer Maimon 210*9bf85fbcSTomer Maimon /* calculate ADC clock sample rate */ 211*9bf85fbcSTomer Maimon reg_con = ioread32(info->regs + NPCM_ADCCON); 212*9bf85fbcSTomer Maimon div = reg_con & NPCM_ADCCON_DIV_MASK; 213*9bf85fbcSTomer Maimon div = div >> NPCM_ADCCON_DIV_SHIFT; 214*9bf85fbcSTomer Maimon info->adc_sample_hz = clk_get_rate(info->adc_clk) / ((div + 1) * 2); 215*9bf85fbcSTomer Maimon 216*9bf85fbcSTomer Maimon if (of_device_is_compatible(np, "nuvoton,npcm750-adc")) { 217*9bf85fbcSTomer Maimon info->rst_regmap = syscon_regmap_lookup_by_compatible 218*9bf85fbcSTomer Maimon ("nuvoton,npcm750-rst"); 219*9bf85fbcSTomer Maimon if (IS_ERR(info->rst_regmap)) { 220*9bf85fbcSTomer Maimon dev_err(&pdev->dev, "Failed to find nuvoton,npcm750-rst\n"); 221*9bf85fbcSTomer Maimon ret = PTR_ERR(info->rst_regmap); 222*9bf85fbcSTomer Maimon goto err_disable_clk; 223*9bf85fbcSTomer Maimon } 224*9bf85fbcSTomer Maimon } 225*9bf85fbcSTomer Maimon 226*9bf85fbcSTomer Maimon irq = platform_get_irq(pdev, 0); 227*9bf85fbcSTomer Maimon if (irq <= 0) { 228*9bf85fbcSTomer Maimon dev_err(dev, "failed getting interrupt resource\n"); 229*9bf85fbcSTomer Maimon ret = -EINVAL; 230*9bf85fbcSTomer Maimon goto err_disable_clk; 231*9bf85fbcSTomer Maimon } 232*9bf85fbcSTomer Maimon 233*9bf85fbcSTomer Maimon ret = devm_request_irq(&pdev->dev, irq, npcm_adc_isr, 0, 234*9bf85fbcSTomer Maimon "NPCM_ADC", indio_dev); 235*9bf85fbcSTomer Maimon if (ret < 0) { 236*9bf85fbcSTomer Maimon dev_err(dev, "failed requesting interrupt\n"); 237*9bf85fbcSTomer Maimon goto err_disable_clk; 238*9bf85fbcSTomer Maimon } 239*9bf85fbcSTomer Maimon 240*9bf85fbcSTomer Maimon reg_con = ioread32(info->regs + NPCM_ADCCON); 241*9bf85fbcSTomer Maimon info->vref = devm_regulator_get_optional(&pdev->dev, "vref"); 242*9bf85fbcSTomer Maimon if (!IS_ERR(info->vref)) { 243*9bf85fbcSTomer Maimon ret = regulator_enable(info->vref); 244*9bf85fbcSTomer Maimon if (ret) { 245*9bf85fbcSTomer Maimon dev_err(&pdev->dev, "Can't enable ADC reference voltage\n"); 246*9bf85fbcSTomer Maimon goto err_disable_clk; 247*9bf85fbcSTomer Maimon } 248*9bf85fbcSTomer Maimon 249*9bf85fbcSTomer Maimon iowrite32(reg_con & ~NPCM_ADCCON_REFSEL, 250*9bf85fbcSTomer Maimon info->regs + NPCM_ADCCON); 251*9bf85fbcSTomer Maimon } else { 252*9bf85fbcSTomer Maimon /* 253*9bf85fbcSTomer Maimon * Any error which is not ENODEV indicates the regulator 254*9bf85fbcSTomer Maimon * has been specified and so is a failure case. 255*9bf85fbcSTomer Maimon */ 256*9bf85fbcSTomer Maimon if (PTR_ERR(info->vref) != -ENODEV) { 257*9bf85fbcSTomer Maimon ret = PTR_ERR(info->vref); 258*9bf85fbcSTomer Maimon goto err_disable_clk; 259*9bf85fbcSTomer Maimon } 260*9bf85fbcSTomer Maimon 261*9bf85fbcSTomer Maimon /* Use internal reference */ 262*9bf85fbcSTomer Maimon iowrite32(reg_con | NPCM_ADCCON_REFSEL, 263*9bf85fbcSTomer Maimon info->regs + NPCM_ADCCON); 264*9bf85fbcSTomer Maimon } 265*9bf85fbcSTomer Maimon 266*9bf85fbcSTomer Maimon init_waitqueue_head(&info->wq); 267*9bf85fbcSTomer Maimon 268*9bf85fbcSTomer Maimon reg_con = ioread32(info->regs + NPCM_ADCCON); 269*9bf85fbcSTomer Maimon reg_con |= NPCM_ADC_ENABLE; 270*9bf85fbcSTomer Maimon 271*9bf85fbcSTomer Maimon /* Enable the ADC Module */ 272*9bf85fbcSTomer Maimon iowrite32(reg_con, info->regs + NPCM_ADCCON); 273*9bf85fbcSTomer Maimon 274*9bf85fbcSTomer Maimon /* Start ADC conversion */ 275*9bf85fbcSTomer Maimon iowrite32(reg_con | NPCM_ADCCON_ADC_CONV, info->regs + NPCM_ADCCON); 276*9bf85fbcSTomer Maimon 277*9bf85fbcSTomer Maimon platform_set_drvdata(pdev, indio_dev); 278*9bf85fbcSTomer Maimon indio_dev->name = dev_name(&pdev->dev); 279*9bf85fbcSTomer Maimon indio_dev->dev.parent = &pdev->dev; 280*9bf85fbcSTomer Maimon indio_dev->info = &npcm_adc_iio_info; 281*9bf85fbcSTomer Maimon indio_dev->modes = INDIO_DIRECT_MODE; 282*9bf85fbcSTomer Maimon indio_dev->channels = npcm_adc_iio_channels; 283*9bf85fbcSTomer Maimon indio_dev->num_channels = ARRAY_SIZE(npcm_adc_iio_channels); 284*9bf85fbcSTomer Maimon 285*9bf85fbcSTomer Maimon ret = iio_device_register(indio_dev); 286*9bf85fbcSTomer Maimon if (ret) { 287*9bf85fbcSTomer Maimon dev_err(&pdev->dev, "Couldn't register the device.\n"); 288*9bf85fbcSTomer Maimon goto err_iio_register; 289*9bf85fbcSTomer Maimon } 290*9bf85fbcSTomer Maimon 291*9bf85fbcSTomer Maimon pr_info("NPCM ADC driver probed\n"); 292*9bf85fbcSTomer Maimon 293*9bf85fbcSTomer Maimon return 0; 294*9bf85fbcSTomer Maimon 295*9bf85fbcSTomer Maimon err_iio_register: 296*9bf85fbcSTomer Maimon iowrite32(reg_con & ~NPCM_ADCCON_ADC_EN, info->regs + NPCM_ADCCON); 297*9bf85fbcSTomer Maimon if (!IS_ERR(info->vref)) 298*9bf85fbcSTomer Maimon regulator_disable(info->vref); 299*9bf85fbcSTomer Maimon err_disable_clk: 300*9bf85fbcSTomer Maimon clk_disable_unprepare(info->adc_clk); 301*9bf85fbcSTomer Maimon 302*9bf85fbcSTomer Maimon return ret; 303*9bf85fbcSTomer Maimon } 304*9bf85fbcSTomer Maimon 305*9bf85fbcSTomer Maimon static int npcm_adc_remove(struct platform_device *pdev) 306*9bf85fbcSTomer Maimon { 307*9bf85fbcSTomer Maimon struct iio_dev *indio_dev = platform_get_drvdata(pdev); 308*9bf85fbcSTomer Maimon struct npcm_adc *info = iio_priv(indio_dev); 309*9bf85fbcSTomer Maimon u32 regtemp; 310*9bf85fbcSTomer Maimon 311*9bf85fbcSTomer Maimon iio_device_unregister(indio_dev); 312*9bf85fbcSTomer Maimon 313*9bf85fbcSTomer Maimon regtemp = ioread32(info->regs + NPCM_ADCCON); 314*9bf85fbcSTomer Maimon iowrite32(regtemp & ~NPCM_ADCCON_ADC_EN, info->regs + NPCM_ADCCON); 315*9bf85fbcSTomer Maimon if (!IS_ERR(info->vref)) 316*9bf85fbcSTomer Maimon regulator_disable(info->vref); 317*9bf85fbcSTomer Maimon clk_disable_unprepare(info->adc_clk); 318*9bf85fbcSTomer Maimon 319*9bf85fbcSTomer Maimon return 0; 320*9bf85fbcSTomer Maimon } 321*9bf85fbcSTomer Maimon 322*9bf85fbcSTomer Maimon static struct platform_driver npcm_adc_driver = { 323*9bf85fbcSTomer Maimon .probe = npcm_adc_probe, 324*9bf85fbcSTomer Maimon .remove = npcm_adc_remove, 325*9bf85fbcSTomer Maimon .driver = { 326*9bf85fbcSTomer Maimon .name = "npcm_adc", 327*9bf85fbcSTomer Maimon .of_match_table = npcm_adc_match, 328*9bf85fbcSTomer Maimon }, 329*9bf85fbcSTomer Maimon }; 330*9bf85fbcSTomer Maimon 331*9bf85fbcSTomer Maimon module_platform_driver(npcm_adc_driver); 332*9bf85fbcSTomer Maimon 333*9bf85fbcSTomer Maimon MODULE_DESCRIPTION("Nuvoton NPCM ADC Driver"); 334*9bf85fbcSTomer Maimon MODULE_AUTHOR("Tomer Maimon <tomer.maimon@nuvoton.com>"); 335*9bf85fbcSTomer Maimon MODULE_LICENSE("GPL v2"); 336