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