| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * Rockchip Successive Approximation Register (SAR) A/D Converter |
|---|
| 3 | 4 | * 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 | 5 | */ |
|---|
| 15 | 6 | |
|---|
| 16 | 7 | #include <linux/module.h> |
|---|
| .. | .. |
|---|
| 82 | 73 | const struct rockchip_saradc_data *data; |
|---|
| 83 | 74 | u16 last_val; |
|---|
| 84 | 75 | const struct iio_chan_spec *last_chan; |
|---|
| 76 | + struct notifier_block nb; |
|---|
| 85 | 77 | bool suspended; |
|---|
| 86 | 78 | #ifdef CONFIG_ROCKCHIP_SARADC_TEST_CHN |
|---|
| 87 | 79 | bool test; |
|---|
| .. | .. |
|---|
| 321 | 313 | .power_down = rockchip_saradc_power_down_v1, |
|---|
| 322 | 314 | }; |
|---|
| 323 | 315 | |
|---|
| 316 | +static const struct iio_chan_spec rockchip_rk3528_saradc_iio_channels[] = { |
|---|
| 317 | + SARADC_CHANNEL(0, "adc0", 10), |
|---|
| 318 | + SARADC_CHANNEL(1, "adc1", 10), |
|---|
| 319 | + SARADC_CHANNEL(2, "adc2", 10), |
|---|
| 320 | + SARADC_CHANNEL(3, "adc3", 10), |
|---|
| 321 | +}; |
|---|
| 322 | + |
|---|
| 323 | +static const struct rockchip_saradc_data rk3528_saradc_data = { |
|---|
| 324 | + .channels = rockchip_rk3528_saradc_iio_channels, |
|---|
| 325 | + .num_channels = ARRAY_SIZE(rockchip_rk3528_saradc_iio_channels), |
|---|
| 326 | + .clk_rate = 1000000, |
|---|
| 327 | + .start = rockchip_saradc_start_v2, |
|---|
| 328 | + .read = rockchip_saradc_read_v2, |
|---|
| 329 | +}; |
|---|
| 330 | + |
|---|
| 331 | +static const struct iio_chan_spec rockchip_rk3562_saradc_iio_channels[] = { |
|---|
| 332 | + SARADC_CHANNEL(0, "adc0", 10), |
|---|
| 333 | + SARADC_CHANNEL(1, "adc1", 10), |
|---|
| 334 | + SARADC_CHANNEL(2, "adc2", 10), |
|---|
| 335 | + SARADC_CHANNEL(3, "adc3", 10), |
|---|
| 336 | + SARADC_CHANNEL(4, "adc4", 10), |
|---|
| 337 | + SARADC_CHANNEL(5, "adc5", 10), |
|---|
| 338 | + SARADC_CHANNEL(6, "adc6", 10), |
|---|
| 339 | + SARADC_CHANNEL(7, "adc7", 10), |
|---|
| 340 | +}; |
|---|
| 341 | + |
|---|
| 342 | +static const struct rockchip_saradc_data rk3562_saradc_data = { |
|---|
| 343 | + .channels = rockchip_rk3562_saradc_iio_channels, |
|---|
| 344 | + .num_channels = ARRAY_SIZE(rockchip_rk3562_saradc_iio_channels), |
|---|
| 345 | + .clk_rate = 1000000, |
|---|
| 346 | + .start = rockchip_saradc_start_v2, |
|---|
| 347 | + .read = rockchip_saradc_read_v2, |
|---|
| 348 | +}; |
|---|
| 349 | + |
|---|
| 324 | 350 | static const struct iio_chan_spec rockchip_rk3568_saradc_iio_channels[] = { |
|---|
| 325 | 351 | SARADC_CHANNEL(0, "adc0", 10), |
|---|
| 326 | 352 | SARADC_CHANNEL(1, "adc1", 10), |
|---|
| .. | .. |
|---|
| 384 | 410 | .compatible = "rockchip,rk3399-saradc", |
|---|
| 385 | 411 | .data = &rk3399_saradc_data, |
|---|
| 386 | 412 | }, { |
|---|
| 413 | + .compatible = "rockchip,rk3528-saradc", |
|---|
| 414 | + .data = &rk3528_saradc_data, |
|---|
| 415 | + }, { |
|---|
| 416 | + .compatible = "rockchip,rk3562-saradc", |
|---|
| 417 | + .data = &rk3562_saradc_data, |
|---|
| 418 | + }, { |
|---|
| 387 | 419 | .compatible = "rockchip,rk3568-saradc", |
|---|
| 388 | 420 | .data = &rk3568_saradc_data, |
|---|
| 389 | 421 | }, { |
|---|
| .. | .. |
|---|
| 397 | 429 | }; |
|---|
| 398 | 430 | MODULE_DEVICE_TABLE(of, rockchip_saradc_match); |
|---|
| 399 | 431 | |
|---|
| 400 | | -/** |
|---|
| 432 | +/* |
|---|
| 401 | 433 | * Reset SARADC Controller. |
|---|
| 402 | 434 | */ |
|---|
| 403 | 435 | static void rockchip_saradc_reset_controller(struct reset_control *reset) |
|---|
| .. | .. |
|---|
| 468 | 500 | return IRQ_HANDLED; |
|---|
| 469 | 501 | } |
|---|
| 470 | 502 | |
|---|
| 503 | +static int rockchip_saradc_volt_notify(struct notifier_block *nb, |
|---|
| 504 | + unsigned long event, |
|---|
| 505 | + void *data) |
|---|
| 506 | +{ |
|---|
| 507 | + struct rockchip_saradc *info = |
|---|
| 508 | + container_of(nb, struct rockchip_saradc, nb); |
|---|
| 509 | + |
|---|
| 510 | + if (event & REGULATOR_EVENT_VOLTAGE_CHANGE) |
|---|
| 511 | + info->uv_vref = (unsigned long)data; |
|---|
| 512 | + |
|---|
| 513 | + return NOTIFY_OK; |
|---|
| 514 | +} |
|---|
| 515 | + |
|---|
| 516 | +static void rockchip_saradc_regulator_unreg_notifier(void *data) |
|---|
| 517 | +{ |
|---|
| 518 | + struct rockchip_saradc *info = data; |
|---|
| 519 | + |
|---|
| 520 | + regulator_unregister_notifier(info->vref, &info->nb); |
|---|
| 521 | +} |
|---|
| 522 | + |
|---|
| 471 | 523 | #ifdef CONFIG_ROCKCHIP_SARADC_TEST_CHN |
|---|
| 472 | 524 | static ssize_t saradc_test_chn_store(struct device *dev, |
|---|
| 473 | 525 | struct device_attribute *attr, |
|---|
| .. | .. |
|---|
| 492 | 544 | return size; |
|---|
| 493 | 545 | } |
|---|
| 494 | 546 | |
|---|
| 495 | | - if (!info->test && val < SARADC_CTRL_CHN_MASK) { |
|---|
| 547 | + if (!info->test && val <= SARADC_CTRL_CHN_MASK) { |
|---|
| 496 | 548 | info->test = true; |
|---|
| 497 | 549 | info->chn = val; |
|---|
| 498 | 550 | mod_delayed_work(info->wq, &info->work, msecs_to_jiffies(100)); |
|---|
| .. | .. |
|---|
| 594 | 646 | init_completion(&info->completion); |
|---|
| 595 | 647 | |
|---|
| 596 | 648 | irq = platform_get_irq(pdev, 0); |
|---|
| 597 | | - if (irq < 0) { |
|---|
| 598 | | - dev_err(&pdev->dev, "no irq resource?\n"); |
|---|
| 649 | + if (irq < 0) |
|---|
| 599 | 650 | return irq; |
|---|
| 600 | | - } |
|---|
| 601 | 651 | |
|---|
| 602 | 652 | ret = devm_request_irq(&pdev->dev, irq, rockchip_saradc_isr, |
|---|
| 603 | 653 | 0, dev_name(&pdev->dev), info); |
|---|
| .. | .. |
|---|
| 651 | 701 | return ret; |
|---|
| 652 | 702 | } |
|---|
| 653 | 703 | |
|---|
| 654 | | - info->uv_vref = regulator_get_voltage(info->vref); |
|---|
| 655 | | - if (info->uv_vref < 0) { |
|---|
| 704 | + ret = regulator_get_voltage(info->vref); |
|---|
| 705 | + if (ret < 0) { |
|---|
| 656 | 706 | dev_err(&pdev->dev, "failed to get voltage\n"); |
|---|
| 657 | | - ret = info->uv_vref; |
|---|
| 658 | 707 | return ret; |
|---|
| 659 | 708 | } |
|---|
| 709 | + |
|---|
| 710 | + info->uv_vref = ret; |
|---|
| 660 | 711 | |
|---|
| 661 | 712 | ret = clk_prepare_enable(info->pclk); |
|---|
| 662 | 713 | if (ret < 0) { |
|---|
| .. | .. |
|---|
| 687 | 738 | platform_set_drvdata(pdev, indio_dev); |
|---|
| 688 | 739 | |
|---|
| 689 | 740 | indio_dev->name = dev_name(&pdev->dev); |
|---|
| 690 | | - indio_dev->dev.parent = &pdev->dev; |
|---|
| 691 | | - indio_dev->dev.of_node = pdev->dev.of_node; |
|---|
| 692 | 741 | indio_dev->info = &rockchip_saradc_iio_info; |
|---|
| 693 | 742 | indio_dev->modes = INDIO_DIRECT_MODE; |
|---|
| 694 | 743 | |
|---|
| .. | .. |
|---|
| 697 | 746 | ret = devm_iio_triggered_buffer_setup(&indio_dev->dev, indio_dev, NULL, |
|---|
| 698 | 747 | rockchip_saradc_trigger_handler, |
|---|
| 699 | 748 | NULL); |
|---|
| 749 | + if (ret) |
|---|
| 750 | + return ret; |
|---|
| 751 | + |
|---|
| 752 | + info->nb.notifier_call = rockchip_saradc_volt_notify; |
|---|
| 753 | + ret = regulator_register_notifier(info->vref, &info->nb); |
|---|
| 754 | + if (ret) |
|---|
| 755 | + return ret; |
|---|
| 756 | + |
|---|
| 757 | + ret = devm_add_action_or_reset(&pdev->dev, |
|---|
| 758 | + rockchip_saradc_regulator_unreg_notifier, |
|---|
| 759 | + info); |
|---|
| 700 | 760 | if (ret) |
|---|
| 701 | 761 | return ret; |
|---|
| 702 | 762 | |
|---|
| .. | .. |
|---|
| 782 | 842 | }, |
|---|
| 783 | 843 | }; |
|---|
| 784 | 844 | |
|---|
| 785 | | -#ifdef CONFIG_ROCKCHIP_THUNDER_BOOT |
|---|
| 786 | | -static int __init rockchip_saradc_driver_init(void) |
|---|
| 787 | | -{ |
|---|
| 788 | | - return platform_driver_register(&rockchip_saradc_driver); |
|---|
| 789 | | -} |
|---|
| 790 | | -fs_initcall(rockchip_saradc_driver_init); |
|---|
| 791 | | - |
|---|
| 792 | | -static void __exit rockchip_saradc_driver_exit(void) |
|---|
| 793 | | -{ |
|---|
| 794 | | - platform_driver_unregister(&rockchip_saradc_driver); |
|---|
| 795 | | -} |
|---|
| 796 | | -module_exit(rockchip_saradc_driver_exit); |
|---|
| 797 | | -#else |
|---|
| 798 | 845 | module_platform_driver(rockchip_saradc_driver); |
|---|
| 799 | | -#endif |
|---|
| 800 | 846 | |
|---|
| 801 | 847 | MODULE_AUTHOR("Heiko Stuebner <heiko@sntech.de>"); |
|---|
| 802 | 848 | MODULE_DESCRIPTION("Rockchip SARADC driver"); |
|---|