1 /* 2 * Rockchip Successive Approximation Register (SAR) A/D Converter 3 * Copyright (C) 2014 ROCKCHIP, Inc. 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation; either version 2 of the License, or 8 * (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 */ 15 16 #include <linux/module.h> 17 #include <linux/platform_device.h> 18 #include <linux/interrupt.h> 19 #include <linux/io.h> 20 #include <linux/of.h> 21 #include <linux/of_device.h> 22 #include <linux/clk.h> 23 #include <linux/completion.h> 24 #include <linux/regulator/consumer.h> 25 #include <linux/iio/iio.h> 26 27 #define SARADC_DATA 0x00 28 29 #define SARADC_STAS 0x04 30 #define SARADC_STAS_BUSY BIT(0) 31 32 #define SARADC_CTRL 0x08 33 #define SARADC_CTRL_IRQ_STATUS BIT(6) 34 #define SARADC_CTRL_IRQ_ENABLE BIT(5) 35 #define SARADC_CTRL_POWER_CTRL BIT(3) 36 #define SARADC_CTRL_CHN_MASK 0x7 37 38 #define SARADC_DLY_PU_SOC 0x0c 39 #define SARADC_DLY_PU_SOC_MASK 0x3f 40 41 #define SARADC_TIMEOUT msecs_to_jiffies(100) 42 43 struct rockchip_saradc_data { 44 int num_bits; 45 const struct iio_chan_spec *channels; 46 int num_channels; 47 unsigned long clk_rate; 48 }; 49 50 struct rockchip_saradc { 51 void __iomem *regs; 52 struct clk *pclk; 53 struct clk *clk; 54 struct completion completion; 55 struct regulator *vref; 56 const struct rockchip_saradc_data *data; 57 u16 last_val; 58 }; 59 60 static int rockchip_saradc_read_raw(struct iio_dev *indio_dev, 61 struct iio_chan_spec const *chan, 62 int *val, int *val2, long mask) 63 { 64 struct rockchip_saradc *info = iio_priv(indio_dev); 65 int ret; 66 67 switch (mask) { 68 case IIO_CHAN_INFO_RAW: 69 mutex_lock(&indio_dev->mlock); 70 71 reinit_completion(&info->completion); 72 73 /* 8 clock periods as delay between power up and start cmd */ 74 writel_relaxed(8, info->regs + SARADC_DLY_PU_SOC); 75 76 /* Select the channel to be used and trigger conversion */ 77 writel(SARADC_CTRL_POWER_CTRL 78 | (chan->channel & SARADC_CTRL_CHN_MASK) 79 | SARADC_CTRL_IRQ_ENABLE, 80 info->regs + SARADC_CTRL); 81 82 if (!wait_for_completion_timeout(&info->completion, 83 SARADC_TIMEOUT)) { 84 writel_relaxed(0, info->regs + SARADC_CTRL); 85 mutex_unlock(&indio_dev->mlock); 86 return -ETIMEDOUT; 87 } 88 89 *val = info->last_val; 90 mutex_unlock(&indio_dev->mlock); 91 return IIO_VAL_INT; 92 case IIO_CHAN_INFO_SCALE: 93 ret = regulator_get_voltage(info->vref); 94 if (ret < 0) { 95 dev_err(&indio_dev->dev, "failed to get voltage\n"); 96 return ret; 97 } 98 99 *val = ret / 1000; 100 *val2 = info->data->num_bits; 101 return IIO_VAL_FRACTIONAL_LOG2; 102 default: 103 return -EINVAL; 104 } 105 } 106 107 static irqreturn_t rockchip_saradc_isr(int irq, void *dev_id) 108 { 109 struct rockchip_saradc *info = (struct rockchip_saradc *)dev_id; 110 111 /* Read value */ 112 info->last_val = readl_relaxed(info->regs + SARADC_DATA); 113 info->last_val &= GENMASK(info->data->num_bits - 1, 0); 114 115 /* Clear irq & power down adc */ 116 writel_relaxed(0, info->regs + SARADC_CTRL); 117 118 complete(&info->completion); 119 120 return IRQ_HANDLED; 121 } 122 123 static const struct iio_info rockchip_saradc_iio_info = { 124 .read_raw = rockchip_saradc_read_raw, 125 .driver_module = THIS_MODULE, 126 }; 127 128 #define ADC_CHANNEL(_index, _id) { \ 129 .type = IIO_VOLTAGE, \ 130 .indexed = 1, \ 131 .channel = _index, \ 132 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ 133 .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \ 134 .datasheet_name = _id, \ 135 } 136 137 static const struct iio_chan_spec rockchip_saradc_iio_channels[] = { 138 ADC_CHANNEL(0, "adc0"), 139 ADC_CHANNEL(1, "adc1"), 140 ADC_CHANNEL(2, "adc2"), 141 }; 142 143 static const struct rockchip_saradc_data saradc_data = { 144 .num_bits = 10, 145 .channels = rockchip_saradc_iio_channels, 146 .num_channels = ARRAY_SIZE(rockchip_saradc_iio_channels), 147 .clk_rate = 1000000, 148 }; 149 150 static const struct iio_chan_spec rockchip_rk3066_tsadc_iio_channels[] = { 151 ADC_CHANNEL(0, "adc0"), 152 ADC_CHANNEL(1, "adc1"), 153 }; 154 155 static const struct rockchip_saradc_data rk3066_tsadc_data = { 156 .num_bits = 12, 157 .channels = rockchip_rk3066_tsadc_iio_channels, 158 .num_channels = ARRAY_SIZE(rockchip_rk3066_tsadc_iio_channels), 159 .clk_rate = 50000, 160 }; 161 162 static const struct iio_chan_spec rockchip_rk3399_saradc_iio_channels[] = { 163 ADC_CHANNEL(0, "adc0"), 164 ADC_CHANNEL(1, "adc1"), 165 ADC_CHANNEL(2, "adc2"), 166 ADC_CHANNEL(3, "adc3"), 167 ADC_CHANNEL(4, "adc4"), 168 ADC_CHANNEL(5, "adc5"), 169 }; 170 171 static const struct rockchip_saradc_data rk3399_saradc_data = { 172 .num_bits = 10, 173 .channels = rockchip_rk3399_saradc_iio_channels, 174 .num_channels = ARRAY_SIZE(rockchip_rk3399_saradc_iio_channels), 175 .clk_rate = 1000000, 176 }; 177 178 static const struct of_device_id rockchip_saradc_match[] = { 179 { 180 .compatible = "rockchip,saradc", 181 .data = &saradc_data, 182 }, { 183 .compatible = "rockchip,rk3066-tsadc", 184 .data = &rk3066_tsadc_data, 185 }, { 186 .compatible = "rockchip,rk3399-saradc", 187 .data = &rk3399_saradc_data, 188 }, 189 {}, 190 }; 191 MODULE_DEVICE_TABLE(of, rockchip_saradc_match); 192 193 static int rockchip_saradc_probe(struct platform_device *pdev) 194 { 195 struct rockchip_saradc *info = NULL; 196 struct device_node *np = pdev->dev.of_node; 197 struct iio_dev *indio_dev = NULL; 198 struct resource *mem; 199 const struct of_device_id *match; 200 int ret; 201 int irq; 202 203 if (!np) 204 return -ENODEV; 205 206 indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*info)); 207 if (!indio_dev) { 208 dev_err(&pdev->dev, "failed allocating iio device\n"); 209 return -ENOMEM; 210 } 211 info = iio_priv(indio_dev); 212 213 match = of_match_device(rockchip_saradc_match, &pdev->dev); 214 info->data = match->data; 215 216 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); 217 info->regs = devm_ioremap_resource(&pdev->dev, mem); 218 if (IS_ERR(info->regs)) 219 return PTR_ERR(info->regs); 220 221 init_completion(&info->completion); 222 223 irq = platform_get_irq(pdev, 0); 224 if (irq < 0) { 225 dev_err(&pdev->dev, "no irq resource?\n"); 226 return irq; 227 } 228 229 ret = devm_request_irq(&pdev->dev, irq, rockchip_saradc_isr, 230 0, dev_name(&pdev->dev), info); 231 if (ret < 0) { 232 dev_err(&pdev->dev, "failed requesting irq %d\n", irq); 233 return ret; 234 } 235 236 info->pclk = devm_clk_get(&pdev->dev, "apb_pclk"); 237 if (IS_ERR(info->pclk)) { 238 dev_err(&pdev->dev, "failed to get pclk\n"); 239 return PTR_ERR(info->pclk); 240 } 241 242 info->clk = devm_clk_get(&pdev->dev, "saradc"); 243 if (IS_ERR(info->clk)) { 244 dev_err(&pdev->dev, "failed to get adc clock\n"); 245 return PTR_ERR(info->clk); 246 } 247 248 info->vref = devm_regulator_get(&pdev->dev, "vref"); 249 if (IS_ERR(info->vref)) { 250 dev_err(&pdev->dev, "failed to get regulator, %ld\n", 251 PTR_ERR(info->vref)); 252 return PTR_ERR(info->vref); 253 } 254 255 /* 256 * Use a default value for the converter clock. 257 * This may become user-configurable in the future. 258 */ 259 ret = clk_set_rate(info->clk, info->data->clk_rate); 260 if (ret < 0) { 261 dev_err(&pdev->dev, "failed to set adc clk rate, %d\n", ret); 262 return ret; 263 } 264 265 ret = regulator_enable(info->vref); 266 if (ret < 0) { 267 dev_err(&pdev->dev, "failed to enable vref regulator\n"); 268 return ret; 269 } 270 271 ret = clk_prepare_enable(info->pclk); 272 if (ret < 0) { 273 dev_err(&pdev->dev, "failed to enable pclk\n"); 274 goto err_reg_voltage; 275 } 276 277 ret = clk_prepare_enable(info->clk); 278 if (ret < 0) { 279 dev_err(&pdev->dev, "failed to enable converter clock\n"); 280 goto err_pclk; 281 } 282 283 platform_set_drvdata(pdev, indio_dev); 284 285 indio_dev->name = dev_name(&pdev->dev); 286 indio_dev->dev.parent = &pdev->dev; 287 indio_dev->dev.of_node = pdev->dev.of_node; 288 indio_dev->info = &rockchip_saradc_iio_info; 289 indio_dev->modes = INDIO_DIRECT_MODE; 290 291 indio_dev->channels = info->data->channels; 292 indio_dev->num_channels = info->data->num_channels; 293 294 ret = iio_device_register(indio_dev); 295 if (ret) 296 goto err_clk; 297 298 return 0; 299 300 err_clk: 301 clk_disable_unprepare(info->clk); 302 err_pclk: 303 clk_disable_unprepare(info->pclk); 304 err_reg_voltage: 305 regulator_disable(info->vref); 306 return ret; 307 } 308 309 static int rockchip_saradc_remove(struct platform_device *pdev) 310 { 311 struct iio_dev *indio_dev = platform_get_drvdata(pdev); 312 struct rockchip_saradc *info = iio_priv(indio_dev); 313 314 iio_device_unregister(indio_dev); 315 clk_disable_unprepare(info->clk); 316 clk_disable_unprepare(info->pclk); 317 regulator_disable(info->vref); 318 319 return 0; 320 } 321 322 #ifdef CONFIG_PM_SLEEP 323 static int rockchip_saradc_suspend(struct device *dev) 324 { 325 struct iio_dev *indio_dev = dev_get_drvdata(dev); 326 struct rockchip_saradc *info = iio_priv(indio_dev); 327 328 clk_disable_unprepare(info->clk); 329 clk_disable_unprepare(info->pclk); 330 regulator_disable(info->vref); 331 332 return 0; 333 } 334 335 static int rockchip_saradc_resume(struct device *dev) 336 { 337 struct iio_dev *indio_dev = dev_get_drvdata(dev); 338 struct rockchip_saradc *info = iio_priv(indio_dev); 339 int ret; 340 341 ret = regulator_enable(info->vref); 342 if (ret) 343 return ret; 344 345 ret = clk_prepare_enable(info->pclk); 346 if (ret) 347 return ret; 348 349 ret = clk_prepare_enable(info->clk); 350 if (ret) 351 return ret; 352 353 return ret; 354 } 355 #endif 356 357 static SIMPLE_DEV_PM_OPS(rockchip_saradc_pm_ops, 358 rockchip_saradc_suspend, rockchip_saradc_resume); 359 360 static struct platform_driver rockchip_saradc_driver = { 361 .probe = rockchip_saradc_probe, 362 .remove = rockchip_saradc_remove, 363 .driver = { 364 .name = "rockchip-saradc", 365 .of_match_table = rockchip_saradc_match, 366 .pm = &rockchip_saradc_pm_ops, 367 }, 368 }; 369 370 module_platform_driver(rockchip_saradc_driver); 371 372 MODULE_AUTHOR("Heiko Stuebner <heiko@sntech.de>"); 373 MODULE_DESCRIPTION("Rockchip SARADC driver"); 374 MODULE_LICENSE("GPL v2"); 375