FILE
rzt2h_adc.c
File preview with syntax highlighting.
linux-6.19.14/drivers/iio/adc/rzt2h_adc.c
1// SPDX-License-Identifier: GPL-2.0 2 3#include <linux/bitfield.h> 4#include <linux/cleanup.h> 5#include <linux/completion.h> 6#include <linux/delay.h> 7#include <linux/iio/adc-helpers.h> 8#include <linux/iio/iio.h> 9#include <linux/interrupt.h> 10#include <linux/io.h> 11#include <linux/iopoll.h> 12#include <linux/mod_devicetable.h> 13#include <linux/module.h> 14#include <linux/platform_device.h> 15#include <linux/pm_runtime.h> 16#include <linux/property.h> 17 18#define RZT2H_ADCSR_REG 0x00 19#define RZT2H_ADCSR_ADIE_MASK BIT(12) 20#define RZT2H_ADCSR_ADCS_MASK GENMASK(14, 13) 21#define RZT2H_ADCSR_ADCS_SINGLE 0b00 22#define RZT2H_ADCSR_ADST_MASK BIT(15) 23 24#define RZT2H_ADANSA0_REG 0x04 25#define RZT2H_ADANSA0_CH_MASK(x) BIT(x) 26 27#define RZT2H_ADDR_REG(x) (0x20 + 0x2 * (x)) 28 29#define RZT2H_ADCALCTL_REG 0x1f0 30#define RZT2H_ADCALCTL_CAL_MASK BIT(0) 31#define RZT2H_ADCALCTL_CAL_RDY_MASK BIT(1) 32#define RZT2H_ADCALCTL_CAL_ERR_MASK BIT(2) 33 34#define RZT2H_ADC_MAX_CHANNELS 16 35 36struct rzt2h_adc { 37 void __iomem *base; 38 struct device *dev; 39 40 struct completion completion; 41 /* lock to protect against multiple access to the device */ 42 struct mutex lock; 43 44 const struct iio_chan_spec *channels; 45 unsigned int num_channels; 46 unsigned int max_channels; 47}; 48 49static void rzt2h_adc_start(struct rzt2h_adc *adc, unsigned int conversion_type) 50{ 51 u16 reg; 52 53 reg = readw(adc->base + RZT2H_ADCSR_REG); 54 55 /* Set conversion type */ 56 FIELD_MODIFY(RZT2H_ADCSR_ADCS_MASK, ®, conversion_type); 57 58 /* Set end of conversion interrupt and start bit. */ 59 reg |= RZT2H_ADCSR_ADIE_MASK | RZT2H_ADCSR_ADST_MASK; 60 61 writew(reg, adc->base + RZT2H_ADCSR_REG); 62} 63 64static void rzt2h_adc_stop(struct rzt2h_adc *adc) 65{ 66 u16 reg; 67 68 reg = readw(adc->base + RZT2H_ADCSR_REG); 69 70 /* Clear end of conversion interrupt and start bit. */ 71 reg &= ~(RZT2H_ADCSR_ADIE_MASK | RZT2H_ADCSR_ADST_MASK); 72 73 writew(reg, adc->base + RZT2H_ADCSR_REG); 74} 75 76static int rzt2h_adc_read_single(struct rzt2h_adc *adc, unsigned int ch, int *val) 77{ 78 int ret; 79 80 ret = pm_runtime_resume_and_get(adc->dev); 81 if (ret) 82 return ret; 83 84 mutex_lock(&adc->lock); 85 86 reinit_completion(&adc->completion); 87 88 /* Enable a single channel */ 89 writew(RZT2H_ADANSA0_CH_MASK(ch), adc->base + RZT2H_ADANSA0_REG); 90 91 rzt2h_adc_start(adc, RZT2H_ADCSR_ADCS_SINGLE); 92 93 /* 94 * Datasheet Page 2770, Table 41.1: 95 * 0.32us per channel when sample-and-hold circuits are not in use. 96 */ 97 ret = wait_for_completion_timeout(&adc->completion, usecs_to_jiffies(1)); 98 if (!ret) { 99 ret = -ETIMEDOUT; 100 goto disable; 101 } 102 103 *val = readw(adc->base + RZT2H_ADDR_REG(ch)); 104 ret = IIO_VAL_INT; 105 106disable: 107 rzt2h_adc_stop(adc); 108 109 mutex_unlock(&adc->lock); 110 111 pm_runtime_put_autosuspend(adc->dev); 112 113 return ret; 114} 115 116static void rzt2h_adc_set_cal(struct rzt2h_adc *adc, bool cal) 117{ 118 u16 val; 119 120 val = readw(adc->base + RZT2H_ADCALCTL_REG); 121 if (cal) 122 val |= RZT2H_ADCALCTL_CAL_MASK; 123 else 124 val &= ~RZT2H_ADCALCTL_CAL_MASK; 125 126 writew(val, adc->base + RZT2H_ADCALCTL_REG); 127} 128 129static int rzt2h_adc_calibrate(struct rzt2h_adc *adc) 130{ 131 u16 val; 132 int ret; 133 134 rzt2h_adc_set_cal(adc, true); 135 136 ret = read_poll_timeout(readw, val, val & RZT2H_ADCALCTL_CAL_RDY_MASK, 137 200, 1000, true, adc->base + RZT2H_ADCALCTL_REG); 138 if (ret) { 139 dev_err(adc->dev, "Calibration timed out: %d\n", ret); 140 return ret; 141 } 142 143 rzt2h_adc_set_cal(adc, false); 144 145 if (val & RZT2H_ADCALCTL_CAL_ERR_MASK) { 146 dev_err(adc->dev, "Calibration failed\n"); 147 return -EINVAL; 148 } 149 150 return 0; 151} 152 153static int rzt2h_adc_read_raw(struct iio_dev *indio_dev, 154 struct iio_chan_spec const *chan, 155 int *val, int *val2, long mask) 156{ 157 struct rzt2h_adc *adc = iio_priv(indio_dev); 158 159 switch (mask) { 160 case IIO_CHAN_INFO_RAW: 161 return rzt2h_adc_read_single(adc, chan->channel, val); 162 case IIO_CHAN_INFO_SCALE: 163 *val = 1800; 164 *val2 = 12; 165 return IIO_VAL_FRACTIONAL_LOG2; 166 default: 167 return -EINVAL; 168 } 169} 170 171static const struct iio_info rzt2h_adc_iio_info = { 172 .read_raw = rzt2h_adc_read_raw, 173}; 174 175static irqreturn_t rzt2h_adc_isr(int irq, void *private) 176{ 177 struct rzt2h_adc *adc = private; 178 179 complete(&adc->completion); 180 181 return IRQ_HANDLED; 182} 183 184static const struct iio_chan_spec rzt2h_adc_chan_template = { 185 .indexed = 1, 186 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | 187 BIT(IIO_CHAN_INFO_SCALE), 188 .type = IIO_VOLTAGE, 189}; 190 191static int rzt2h_adc_parse_properties(struct rzt2h_adc *adc) 192{ 193 struct iio_chan_spec *chan_array; 194 unsigned int i; 195 int ret; 196 197 ret = devm_iio_adc_device_alloc_chaninfo_se(adc->dev, 198 &rzt2h_adc_chan_template, 199 RZT2H_ADC_MAX_CHANNELS - 1, 200 &chan_array); 201 if (ret < 0) 202 return dev_err_probe(adc->dev, ret, "Failed to read channel info"); 203 204 adc->num_channels = ret; 205 adc->channels = chan_array; 206 207 for (i = 0; i < adc->num_channels; i++) 208 if (chan_array[i].channel + 1 > adc->max_channels) 209 adc->max_channels = chan_array[i].channel + 1; 210 211 return 0; 212} 213 214static int rzt2h_adc_probe(struct platform_device *pdev) 215{ 216 struct device *dev = &pdev->dev; 217 struct iio_dev *indio_dev; 218 struct rzt2h_adc *adc; 219 int ret, irq; 220 221 indio_dev = devm_iio_device_alloc(dev, sizeof(*adc)); 222 if (!indio_dev) 223 return -ENOMEM; 224 225 adc = iio_priv(indio_dev); 226 adc->dev = dev; 227 init_completion(&adc->completion); 228 229 ret = devm_mutex_init(dev, &adc->lock); 230 if (ret) 231 return ret; 232 233 platform_set_drvdata(pdev, adc); 234 235 ret = rzt2h_adc_parse_properties(adc); 236 if (ret) 237 return ret; 238 239 adc->base = devm_platform_ioremap_resource(pdev, 0); 240 if (IS_ERR(adc->base)) 241 return PTR_ERR(adc->base); 242 243 pm_runtime_set_autosuspend_delay(dev, 300); 244 pm_runtime_use_autosuspend(dev); 245 ret = devm_pm_runtime_enable(dev); 246 if (ret) 247 return ret; 248 249 irq = platform_get_irq_byname(pdev, "adi"); 250 if (irq < 0) 251 return irq; 252 253 ret = devm_request_irq(dev, irq, rzt2h_adc_isr, 0, dev_name(dev), adc); 254 if (ret) 255 return ret; 256 257 indio_dev->name = "rzt2h-adc"; 258 indio_dev->info = &rzt2h_adc_iio_info; 259 indio_dev->modes = INDIO_DIRECT_MODE; 260 indio_dev->channels = adc->channels; 261 indio_dev->num_channels = adc->num_channels; 262 263 return devm_iio_device_register(dev, indio_dev); 264} 265 266static const struct of_device_id rzt2h_adc_match[] = { 267 { .compatible = "renesas,r9a09g077-adc" }, 268 { } 269}; 270MODULE_DEVICE_TABLE(of, rzt2h_adc_match); 271 272static int rzt2h_adc_pm_runtime_resume(struct device *dev) 273{ 274 struct rzt2h_adc *adc = dev_get_drvdata(dev); 275 276 /* 277 * Datasheet Page 2810, Section 41.5.6: 278 * After release from the module-stop state, wait for at least 279 * 0.5 µs before starting A/D conversion. 280 */ 281 fsleep(1); 282 283 return rzt2h_adc_calibrate(adc); 284} 285 286static const struct dev_pm_ops rzt2h_adc_pm_ops = { 287 RUNTIME_PM_OPS(NULL, rzt2h_adc_pm_runtime_resume, NULL) 288}; 289 290static struct platform_driver rzt2h_adc_driver = { 291 .probe = rzt2h_adc_probe, 292 .driver = { 293 .name = "rzt2h-adc", 294 .of_match_table = rzt2h_adc_match, 295 .pm = pm_ptr(&rzt2h_adc_pm_ops), 296 }, 297}; 298 299module_platform_driver(rzt2h_adc_driver); 300 301MODULE_AUTHOR("Cosmin Tanislav <cosmin-gabriel.tanislav.xa@renesas.com>"); 302MODULE_DESCRIPTION("Renesas RZ/T2H / RZ/N2H ADC driver"); 303MODULE_LICENSE("GPL"); 304MODULE_IMPORT_NS("IIO_DRIVER");
~/
Read-only file preview.