| .. | .. |
|---|
| 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; |
|---|
| .. | .. |
|---|
| 336 | 328 | .read = rockchip_saradc_read_v2, |
|---|
| 337 | 329 | }; |
|---|
| 338 | 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 | + |
|---|
| 339 | 350 | static const struct iio_chan_spec rockchip_rk3568_saradc_iio_channels[] = { |
|---|
| 340 | 351 | SARADC_CHANNEL(0, "adc0", 10), |
|---|
| 341 | 352 | SARADC_CHANNEL(1, "adc1", 10), |
|---|
| .. | .. |
|---|
| 402 | 413 | .compatible = "rockchip,rk3528-saradc", |
|---|
| 403 | 414 | .data = &rk3528_saradc_data, |
|---|
| 404 | 415 | }, { |
|---|
| 416 | + .compatible = "rockchip,rk3562-saradc", |
|---|
| 417 | + .data = &rk3562_saradc_data, |
|---|
| 418 | + }, { |
|---|
| 405 | 419 | .compatible = "rockchip,rk3568-saradc", |
|---|
| 406 | 420 | .data = &rk3568_saradc_data, |
|---|
| 407 | 421 | }, { |
|---|
| .. | .. |
|---|
| 415 | 429 | }; |
|---|
| 416 | 430 | MODULE_DEVICE_TABLE(of, rockchip_saradc_match); |
|---|
| 417 | 431 | |
|---|
| 418 | | -/** |
|---|
| 432 | +/* |
|---|
| 419 | 433 | * Reset SARADC Controller. |
|---|
| 420 | 434 | */ |
|---|
| 421 | 435 | static void rockchip_saradc_reset_controller(struct reset_control *reset) |
|---|
| .. | .. |
|---|
| 486 | 500 | return IRQ_HANDLED; |
|---|
| 487 | 501 | } |
|---|
| 488 | 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 | + |
|---|
| 489 | 523 | #ifdef CONFIG_ROCKCHIP_SARADC_TEST_CHN |
|---|
| 490 | 524 | static ssize_t saradc_test_chn_store(struct device *dev, |
|---|
| 491 | 525 | struct device_attribute *attr, |
|---|
| .. | .. |
|---|
| 510 | 544 | return size; |
|---|
| 511 | 545 | } |
|---|
| 512 | 546 | |
|---|
| 513 | | - if (!info->test && val < SARADC_CTRL_CHN_MASK) { |
|---|
| 547 | + if (!info->test && val <= SARADC_CTRL_CHN_MASK) { |
|---|
| 514 | 548 | info->test = true; |
|---|
| 515 | 549 | info->chn = val; |
|---|
| 516 | 550 | mod_delayed_work(info->wq, &info->work, msecs_to_jiffies(100)); |
|---|
| .. | .. |
|---|
| 612 | 646 | init_completion(&info->completion); |
|---|
| 613 | 647 | |
|---|
| 614 | 648 | irq = platform_get_irq(pdev, 0); |
|---|
| 615 | | - if (irq < 0) { |
|---|
| 616 | | - dev_err(&pdev->dev, "no irq resource?\n"); |
|---|
| 649 | + if (irq < 0) |
|---|
| 617 | 650 | return irq; |
|---|
| 618 | | - } |
|---|
| 619 | 651 | |
|---|
| 620 | 652 | ret = devm_request_irq(&pdev->dev, irq, rockchip_saradc_isr, |
|---|
| 621 | 653 | 0, dev_name(&pdev->dev), info); |
|---|
| .. | .. |
|---|
| 669 | 701 | return ret; |
|---|
| 670 | 702 | } |
|---|
| 671 | 703 | |
|---|
| 672 | | - info->uv_vref = regulator_get_voltage(info->vref); |
|---|
| 673 | | - if (info->uv_vref < 0) { |
|---|
| 704 | + ret = regulator_get_voltage(info->vref); |
|---|
| 705 | + if (ret < 0) { |
|---|
| 674 | 706 | dev_err(&pdev->dev, "failed to get voltage\n"); |
|---|
| 675 | | - ret = info->uv_vref; |
|---|
| 676 | 707 | return ret; |
|---|
| 677 | 708 | } |
|---|
| 709 | + |
|---|
| 710 | + info->uv_vref = ret; |
|---|
| 678 | 711 | |
|---|
| 679 | 712 | ret = clk_prepare_enable(info->pclk); |
|---|
| 680 | 713 | if (ret < 0) { |
|---|
| .. | .. |
|---|
| 705 | 738 | platform_set_drvdata(pdev, indio_dev); |
|---|
| 706 | 739 | |
|---|
| 707 | 740 | indio_dev->name = dev_name(&pdev->dev); |
|---|
| 708 | | - indio_dev->dev.parent = &pdev->dev; |
|---|
| 709 | | - indio_dev->dev.of_node = pdev->dev.of_node; |
|---|
| 710 | 741 | indio_dev->info = &rockchip_saradc_iio_info; |
|---|
| 711 | 742 | indio_dev->modes = INDIO_DIRECT_MODE; |
|---|
| 712 | 743 | |
|---|
| .. | .. |
|---|
| 715 | 746 | ret = devm_iio_triggered_buffer_setup(&indio_dev->dev, indio_dev, NULL, |
|---|
| 716 | 747 | rockchip_saradc_trigger_handler, |
|---|
| 717 | 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); |
|---|
| 718 | 760 | if (ret) |
|---|
| 719 | 761 | return ret; |
|---|
| 720 | 762 | |
|---|
| .. | .. |
|---|
| 800 | 842 | }, |
|---|
| 801 | 843 | }; |
|---|
| 802 | 844 | |
|---|
| 803 | | -#ifdef CONFIG_ROCKCHIP_THUNDER_BOOT |
|---|
| 804 | | -static int __init rockchip_saradc_driver_init(void) |
|---|
| 805 | | -{ |
|---|
| 806 | | - return platform_driver_register(&rockchip_saradc_driver); |
|---|
| 807 | | -} |
|---|
| 808 | | -fs_initcall(rockchip_saradc_driver_init); |
|---|
| 809 | | - |
|---|
| 810 | | -static void __exit rockchip_saradc_driver_exit(void) |
|---|
| 811 | | -{ |
|---|
| 812 | | - platform_driver_unregister(&rockchip_saradc_driver); |
|---|
| 813 | | -} |
|---|
| 814 | | -module_exit(rockchip_saradc_driver_exit); |
|---|
| 815 | | -#else |
|---|
| 816 | 845 | module_platform_driver(rockchip_saradc_driver); |
|---|
| 817 | | -#endif |
|---|
| 818 | 846 | |
|---|
| 819 | 847 | MODULE_AUTHOR("Heiko Stuebner <heiko@sntech.de>"); |
|---|
| 820 | 848 | MODULE_DESCRIPTION("Rockchip SARADC driver"); |
|---|