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