598 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * Rockchip Successive Approximation Register (SAR) A/D Converter4 * Copyright (C) 2014 ROCKCHIP, Inc.5 */6 7#include <linux/bitfield.h>8#include <linux/module.h>9#include <linux/mutex.h>10#include <linux/platform_device.h>11#include <linux/interrupt.h>12#include <linux/io.h>13#include <linux/of.h>14#include <linux/clk.h>15#include <linux/completion.h>16#include <linux/delay.h>17#include <linux/reset.h>18#include <linux/regulator/consumer.h>19#include <linux/iio/buffer.h>20#include <linux/iio/iio.h>21#include <linux/iio/trigger_consumer.h>22#include <linux/iio/triggered_buffer.h>23 24#define SARADC_DATA 0x0025 26#define SARADC_STAS 0x0427#define SARADC_STAS_BUSY BIT(0)28 29#define SARADC_CTRL 0x0830#define SARADC_CTRL_IRQ_STATUS BIT(6)31#define SARADC_CTRL_IRQ_ENABLE BIT(5)32#define SARADC_CTRL_POWER_CTRL BIT(3)33#define SARADC_CTRL_CHN_MASK 0x734 35#define SARADC_DLY_PU_SOC 0x0c36#define SARADC_DLY_PU_SOC_MASK 0x3f37 38#define SARADC_TIMEOUT msecs_to_jiffies(100)39#define SARADC_MAX_CHANNELS 840 41/* v2 registers */42#define SARADC2_CONV_CON 0x00043#define SARADC_T_PD_SOC 0x00444#define SARADC_T_DAS_SOC 0x00c45#define SARADC2_END_INT_EN 0x10446#define SARADC2_ST_CON 0x10847#define SARADC2_STATUS 0x10c48#define SARADC2_END_INT_ST 0x11049#define SARADC2_DATA_BASE 0x12050 51#define SARADC2_EN_END_INT BIT(0)52#define SARADC2_START BIT(4)53#define SARADC2_SINGLE_MODE BIT(5)54 55#define SARADC2_CONV_CHANNELS GENMASK(3, 0)56 57struct rockchip_saradc;58 59struct rockchip_saradc_data {60 const struct iio_chan_spec *channels;61 int num_channels;62 unsigned long clk_rate;63 void (*start)(struct rockchip_saradc *info, int chn);64 int (*read)(struct rockchip_saradc *info);65 void (*power_down)(struct rockchip_saradc *info);66};67 68struct rockchip_saradc {69 void __iomem *regs;70 struct clk *pclk;71 struct clk *clk;72 struct completion completion;73 struct regulator *vref;74 /* lock to protect against multiple access to the device */75 struct mutex lock;76 int uv_vref;77 struct reset_control *reset;78 const struct rockchip_saradc_data *data;79 u16 last_val;80 const struct iio_chan_spec *last_chan;81 struct notifier_block nb;82};83 84static void rockchip_saradc_reset_controller(struct reset_control *reset);85 86static void rockchip_saradc_start_v1(struct rockchip_saradc *info, int chn)87{88 /* 8 clock periods as delay between power up and start cmd */89 writel_relaxed(8, info->regs + SARADC_DLY_PU_SOC);90 /* Select the channel to be used and trigger conversion */91 writel(SARADC_CTRL_POWER_CTRL | (chn & SARADC_CTRL_CHN_MASK) |92 SARADC_CTRL_IRQ_ENABLE, info->regs + SARADC_CTRL);93}94 95static void rockchip_saradc_start_v2(struct rockchip_saradc *info, int chn)96{97 int val;98 99 if (info->reset)100 rockchip_saradc_reset_controller(info->reset);101 102 writel_relaxed(0xc, info->regs + SARADC_T_DAS_SOC);103 writel_relaxed(0x20, info->regs + SARADC_T_PD_SOC);104 val = FIELD_PREP(SARADC2_EN_END_INT, 1);105 val |= SARADC2_EN_END_INT << 16;106 writel_relaxed(val, info->regs + SARADC2_END_INT_EN);107 val = FIELD_PREP(SARADC2_START, 1) |108 FIELD_PREP(SARADC2_SINGLE_MODE, 1) |109 FIELD_PREP(SARADC2_CONV_CHANNELS, chn);110 val |= (SARADC2_START | SARADC2_SINGLE_MODE | SARADC2_CONV_CHANNELS) << 16;111 writel(val, info->regs + SARADC2_CONV_CON);112}113 114static void rockchip_saradc_start(struct rockchip_saradc *info, int chn)115{116 info->data->start(info, chn);117}118 119static int rockchip_saradc_read_v1(struct rockchip_saradc *info)120{121 return readl_relaxed(info->regs + SARADC_DATA);122}123 124static int rockchip_saradc_read_v2(struct rockchip_saradc *info)125{126 int offset;127 128 /* Clear irq */129 writel_relaxed(0x1, info->regs + SARADC2_END_INT_ST);130 131 offset = SARADC2_DATA_BASE + info->last_chan->channel * 0x4;132 133 return readl_relaxed(info->regs + offset);134}135 136static int rockchip_saradc_read(struct rockchip_saradc *info)137{138 return info->data->read(info);139}140 141static void rockchip_saradc_power_down_v1(struct rockchip_saradc *info)142{143 writel_relaxed(0, info->regs + SARADC_CTRL);144}145 146static void rockchip_saradc_power_down(struct rockchip_saradc *info)147{148 if (info->data->power_down)149 info->data->power_down(info);150}151 152static int rockchip_saradc_conversion(struct rockchip_saradc *info,153 struct iio_chan_spec const *chan)154{155 reinit_completion(&info->completion);156 157 info->last_chan = chan;158 rockchip_saradc_start(info, chan->channel);159 160 if (!wait_for_completion_timeout(&info->completion, SARADC_TIMEOUT))161 return -ETIMEDOUT;162 163 return 0;164}165 166static int rockchip_saradc_read_raw(struct iio_dev *indio_dev,167 struct iio_chan_spec const *chan,168 int *val, int *val2, long mask)169{170 struct rockchip_saradc *info = iio_priv(indio_dev);171 int ret;172 173 switch (mask) {174 case IIO_CHAN_INFO_RAW:175 mutex_lock(&info->lock);176 177 ret = rockchip_saradc_conversion(info, chan);178 if (ret) {179 rockchip_saradc_power_down(info);180 mutex_unlock(&info->lock);181 return ret;182 }183 184 *val = info->last_val;185 mutex_unlock(&info->lock);186 return IIO_VAL_INT;187 case IIO_CHAN_INFO_SCALE:188 *val = info->uv_vref / 1000;189 *val2 = chan->scan_type.realbits;190 return IIO_VAL_FRACTIONAL_LOG2;191 default:192 return -EINVAL;193 }194}195 196static irqreturn_t rockchip_saradc_isr(int irq, void *dev_id)197{198 struct rockchip_saradc *info = dev_id;199 200 /* Read value */201 info->last_val = rockchip_saradc_read(info);202 info->last_val &= GENMASK(info->last_chan->scan_type.realbits - 1, 0);203 204 rockchip_saradc_power_down(info);205 206 complete(&info->completion);207 208 return IRQ_HANDLED;209}210 211static const struct iio_info rockchip_saradc_iio_info = {212 .read_raw = rockchip_saradc_read_raw,213};214 215#define SARADC_CHANNEL(_index, _id, _res) { \216 .type = IIO_VOLTAGE, \217 .indexed = 1, \218 .channel = _index, \219 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \220 .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \221 .datasheet_name = _id, \222 .scan_index = _index, \223 .scan_type = { \224 .sign = 'u', \225 .realbits = _res, \226 .storagebits = 16, \227 .endianness = IIO_CPU, \228 }, \229}230 231static const struct iio_chan_spec rockchip_saradc_iio_channels[] = {232 SARADC_CHANNEL(0, "adc0", 10),233 SARADC_CHANNEL(1, "adc1", 10),234 SARADC_CHANNEL(2, "adc2", 10),235};236 237static const struct rockchip_saradc_data saradc_data = {238 .channels = rockchip_saradc_iio_channels,239 .num_channels = ARRAY_SIZE(rockchip_saradc_iio_channels),240 .clk_rate = 1000000,241 .start = rockchip_saradc_start_v1,242 .read = rockchip_saradc_read_v1,243 .power_down = rockchip_saradc_power_down_v1,244};245 246static const struct iio_chan_spec rockchip_rk3066_tsadc_iio_channels[] = {247 SARADC_CHANNEL(0, "adc0", 12),248 SARADC_CHANNEL(1, "adc1", 12),249};250 251static const struct rockchip_saradc_data rk3066_tsadc_data = {252 .channels = rockchip_rk3066_tsadc_iio_channels,253 .num_channels = ARRAY_SIZE(rockchip_rk3066_tsadc_iio_channels),254 .clk_rate = 50000,255 .start = rockchip_saradc_start_v1,256 .read = rockchip_saradc_read_v1,257 .power_down = rockchip_saradc_power_down_v1,258};259 260static const struct iio_chan_spec rockchip_rk3399_saradc_iio_channels[] = {261 SARADC_CHANNEL(0, "adc0", 10),262 SARADC_CHANNEL(1, "adc1", 10),263 SARADC_CHANNEL(2, "adc2", 10),264 SARADC_CHANNEL(3, "adc3", 10),265 SARADC_CHANNEL(4, "adc4", 10),266 SARADC_CHANNEL(5, "adc5", 10),267};268 269static const struct rockchip_saradc_data rk3399_saradc_data = {270 .channels = rockchip_rk3399_saradc_iio_channels,271 .num_channels = ARRAY_SIZE(rockchip_rk3399_saradc_iio_channels),272 .clk_rate = 1000000,273 .start = rockchip_saradc_start_v1,274 .read = rockchip_saradc_read_v1,275 .power_down = rockchip_saradc_power_down_v1,276};277 278static const struct iio_chan_spec rockchip_rk3568_saradc_iio_channels[] = {279 SARADC_CHANNEL(0, "adc0", 10),280 SARADC_CHANNEL(1, "adc1", 10),281 SARADC_CHANNEL(2, "adc2", 10),282 SARADC_CHANNEL(3, "adc3", 10),283 SARADC_CHANNEL(4, "adc4", 10),284 SARADC_CHANNEL(5, "adc5", 10),285 SARADC_CHANNEL(6, "adc6", 10),286 SARADC_CHANNEL(7, "adc7", 10),287};288 289static const struct rockchip_saradc_data rk3568_saradc_data = {290 .channels = rockchip_rk3568_saradc_iio_channels,291 .num_channels = ARRAY_SIZE(rockchip_rk3568_saradc_iio_channels),292 .clk_rate = 1000000,293 .start = rockchip_saradc_start_v1,294 .read = rockchip_saradc_read_v1,295 .power_down = rockchip_saradc_power_down_v1,296};297 298static const struct iio_chan_spec rockchip_rk3588_saradc_iio_channels[] = {299 SARADC_CHANNEL(0, "adc0", 12),300 SARADC_CHANNEL(1, "adc1", 12),301 SARADC_CHANNEL(2, "adc2", 12),302 SARADC_CHANNEL(3, "adc3", 12),303 SARADC_CHANNEL(4, "adc4", 12),304 SARADC_CHANNEL(5, "adc5", 12),305 SARADC_CHANNEL(6, "adc6", 12),306 SARADC_CHANNEL(7, "adc7", 12),307};308 309static const struct rockchip_saradc_data rk3588_saradc_data = {310 .channels = rockchip_rk3588_saradc_iio_channels,311 .num_channels = ARRAY_SIZE(rockchip_rk3588_saradc_iio_channels),312 .clk_rate = 1000000,313 .start = rockchip_saradc_start_v2,314 .read = rockchip_saradc_read_v2,315};316 317static const struct of_device_id rockchip_saradc_match[] = {318 {319 .compatible = "rockchip,saradc",320 .data = &saradc_data,321 }, {322 .compatible = "rockchip,rk3066-tsadc",323 .data = &rk3066_tsadc_data,324 }, {325 .compatible = "rockchip,rk3399-saradc",326 .data = &rk3399_saradc_data,327 }, {328 .compatible = "rockchip,rk3568-saradc",329 .data = &rk3568_saradc_data,330 }, {331 .compatible = "rockchip,rk3588-saradc",332 .data = &rk3588_saradc_data,333 },334 { }335};336MODULE_DEVICE_TABLE(of, rockchip_saradc_match);337 338/*339 * Reset SARADC Controller.340 */341static void rockchip_saradc_reset_controller(struct reset_control *reset)342{343 reset_control_assert(reset);344 usleep_range(10, 20);345 reset_control_deassert(reset);346}347 348static void rockchip_saradc_regulator_disable(void *data)349{350 struct rockchip_saradc *info = data;351 352 regulator_disable(info->vref);353}354 355static irqreturn_t rockchip_saradc_trigger_handler(int irq, void *p)356{357 struct iio_poll_func *pf = p;358 struct iio_dev *i_dev = pf->indio_dev;359 struct rockchip_saradc *info = iio_priv(i_dev);360 /*361 * @values: each channel takes an u16 value362 * @timestamp: will be 8-byte aligned automatically363 */364 struct {365 u16 values[SARADC_MAX_CHANNELS];366 int64_t timestamp;367 } data;368 int ret;369 int i, j = 0;370 371 mutex_lock(&info->lock);372 373 iio_for_each_active_channel(i_dev, i) {374 const struct iio_chan_spec *chan = &i_dev->channels[i];375 376 ret = rockchip_saradc_conversion(info, chan);377 if (ret) {378 rockchip_saradc_power_down(info);379 goto out;380 }381 382 data.values[j] = info->last_val;383 j++;384 }385 386 iio_push_to_buffers_with_timestamp(i_dev, &data, iio_get_time_ns(i_dev));387out:388 mutex_unlock(&info->lock);389 390 iio_trigger_notify_done(i_dev->trig);391 392 return IRQ_HANDLED;393}394 395static int rockchip_saradc_volt_notify(struct notifier_block *nb,396 unsigned long event, void *data)397{398 struct rockchip_saradc *info =399 container_of(nb, struct rockchip_saradc, nb);400 401 if (event & REGULATOR_EVENT_VOLTAGE_CHANGE)402 info->uv_vref = (unsigned long)data;403 404 return NOTIFY_OK;405}406 407static void rockchip_saradc_regulator_unreg_notifier(void *data)408{409 struct rockchip_saradc *info = data;410 411 regulator_unregister_notifier(info->vref, &info->nb);412}413 414static int rockchip_saradc_probe(struct platform_device *pdev)415{416 const struct rockchip_saradc_data *match_data;417 struct rockchip_saradc *info = NULL;418 struct device_node *np = pdev->dev.of_node;419 struct iio_dev *indio_dev = NULL;420 int ret;421 int irq;422 423 if (!np)424 return -ENODEV;425 426 indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*info));427 if (!indio_dev)428 return dev_err_probe(&pdev->dev, -ENOMEM,429 "failed allocating iio device\n");430 431 info = iio_priv(indio_dev);432 433 match_data = of_device_get_match_data(&pdev->dev);434 if (!match_data)435 return dev_err_probe(&pdev->dev, -ENODEV,436 "failed to match device\n");437 438 info->data = match_data;439 440 /* Sanity check for possible later IP variants with more channels */441 if (info->data->num_channels > SARADC_MAX_CHANNELS)442 return dev_err_probe(&pdev->dev, -EINVAL,443 "max channels exceeded");444 445 info->regs = devm_platform_ioremap_resource(pdev, 0);446 if (IS_ERR(info->regs))447 return PTR_ERR(info->regs);448 449 /*450 * The reset should be an optional property, as it should work451 * with old devicetrees as well452 */453 info->reset = devm_reset_control_get_optional_exclusive(&pdev->dev,454 "saradc-apb");455 if (IS_ERR(info->reset)) {456 ret = PTR_ERR(info->reset);457 return dev_err_probe(&pdev->dev, ret, "failed to get saradc-apb\n");458 }459 460 init_completion(&info->completion);461 462 irq = platform_get_irq(pdev, 0);463 if (irq < 0)464 return irq;465 466 ret = devm_request_irq(&pdev->dev, irq, rockchip_saradc_isr,467 0, dev_name(&pdev->dev), info);468 if (ret < 0) {469 dev_err(&pdev->dev, "failed requesting irq %d\n", irq);470 return ret;471 }472 473 info->vref = devm_regulator_get(&pdev->dev, "vref");474 if (IS_ERR(info->vref))475 return dev_err_probe(&pdev->dev, PTR_ERR(info->vref),476 "failed to get regulator\n");477 478 if (info->reset)479 rockchip_saradc_reset_controller(info->reset);480 481 /*482 * Use a default value for the converter clock.483 * This may become user-configurable in the future.484 */485 ret = clk_set_rate(info->clk, info->data->clk_rate);486 if (ret < 0)487 return dev_err_probe(&pdev->dev, ret,488 "failed to set adc clk rate\n");489 490 ret = regulator_enable(info->vref);491 if (ret < 0)492 return dev_err_probe(&pdev->dev, ret,493 "failed to enable vref regulator\n");494 495 ret = devm_add_action_or_reset(&pdev->dev,496 rockchip_saradc_regulator_disable, info);497 if (ret)498 return dev_err_probe(&pdev->dev, ret,499 "failed to register devm action\n");500 501 ret = regulator_get_voltage(info->vref);502 if (ret < 0)503 return ret;504 505 info->uv_vref = ret;506 507 info->pclk = devm_clk_get_enabled(&pdev->dev, "apb_pclk");508 if (IS_ERR(info->pclk))509 return dev_err_probe(&pdev->dev, PTR_ERR(info->pclk),510 "failed to get pclk\n");511 512 info->clk = devm_clk_get_enabled(&pdev->dev, "saradc");513 if (IS_ERR(info->clk))514 return dev_err_probe(&pdev->dev, PTR_ERR(info->clk),515 "failed to get adc clock\n");516 517 platform_set_drvdata(pdev, indio_dev);518 519 indio_dev->name = dev_name(&pdev->dev);520 indio_dev->info = &rockchip_saradc_iio_info;521 indio_dev->modes = INDIO_DIRECT_MODE;522 523 indio_dev->channels = info->data->channels;524 indio_dev->num_channels = info->data->num_channels;525 ret = devm_iio_triggered_buffer_setup(&indio_dev->dev, indio_dev, NULL,526 rockchip_saradc_trigger_handler,527 NULL);528 if (ret)529 return ret;530 531 info->nb.notifier_call = rockchip_saradc_volt_notify;532 ret = regulator_register_notifier(info->vref, &info->nb);533 if (ret)534 return ret;535 536 ret = devm_add_action_or_reset(&pdev->dev,537 rockchip_saradc_regulator_unreg_notifier,538 info);539 if (ret)540 return ret;541 542 mutex_init(&info->lock);543 544 return devm_iio_device_register(&pdev->dev, indio_dev);545}546 547static int rockchip_saradc_suspend(struct device *dev)548{549 struct iio_dev *indio_dev = dev_get_drvdata(dev);550 struct rockchip_saradc *info = iio_priv(indio_dev);551 552 clk_disable_unprepare(info->clk);553 clk_disable_unprepare(info->pclk);554 regulator_disable(info->vref);555 556 return 0;557}558 559static int rockchip_saradc_resume(struct device *dev)560{561 struct iio_dev *indio_dev = dev_get_drvdata(dev);562 struct rockchip_saradc *info = iio_priv(indio_dev);563 int ret;564 565 ret = regulator_enable(info->vref);566 if (ret)567 return ret;568 569 ret = clk_prepare_enable(info->pclk);570 if (ret)571 return ret;572 573 ret = clk_prepare_enable(info->clk);574 if (ret)575 clk_disable_unprepare(info->pclk);576 577 return ret;578}579 580static DEFINE_SIMPLE_DEV_PM_OPS(rockchip_saradc_pm_ops,581 rockchip_saradc_suspend,582 rockchip_saradc_resume);583 584static struct platform_driver rockchip_saradc_driver = {585 .probe = rockchip_saradc_probe,586 .driver = {587 .name = "rockchip-saradc",588 .of_match_table = rockchip_saradc_match,589 .pm = pm_sleep_ptr(&rockchip_saradc_pm_ops),590 },591};592 593module_platform_driver(rockchip_saradc_driver);594 595MODULE_AUTHOR("Heiko Stuebner <heiko@sntech.de>");596MODULE_DESCRIPTION("Rockchip SARADC driver");597MODULE_LICENSE("GPL v2");598