162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * dummy.c
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci * Copyright 2010 Wolfson Microelectronics PLC.
662306a36Sopenharmony_ci *
762306a36Sopenharmony_ci * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
862306a36Sopenharmony_ci *
962306a36Sopenharmony_ci * This is useful for systems with mixed controllable and
1062306a36Sopenharmony_ci * non-controllable regulators, as well as for allowing testing on
1162306a36Sopenharmony_ci * systems with no controllable regulators.
1262306a36Sopenharmony_ci */
1362306a36Sopenharmony_ci
1462306a36Sopenharmony_ci#include <linux/err.h>
1562306a36Sopenharmony_ci#include <linux/export.h>
1662306a36Sopenharmony_ci#include <linux/platform_device.h>
1762306a36Sopenharmony_ci#include <linux/regulator/driver.h>
1862306a36Sopenharmony_ci#include <linux/regulator/machine.h>
1962306a36Sopenharmony_ci
2062306a36Sopenharmony_ci#include "dummy.h"
2162306a36Sopenharmony_ci
2262306a36Sopenharmony_cistruct regulator_dev *dummy_regulator_rdev;
2362306a36Sopenharmony_ci
2462306a36Sopenharmony_cistatic const struct regulator_init_data dummy_initdata = {
2562306a36Sopenharmony_ci	.constraints = {
2662306a36Sopenharmony_ci		.always_on = 1,
2762306a36Sopenharmony_ci	},
2862306a36Sopenharmony_ci};
2962306a36Sopenharmony_ci
3062306a36Sopenharmony_cistatic const struct regulator_ops dummy_ops;
3162306a36Sopenharmony_ci
3262306a36Sopenharmony_cistatic const struct regulator_desc dummy_desc = {
3362306a36Sopenharmony_ci	.name = "regulator-dummy",
3462306a36Sopenharmony_ci	.id = -1,
3562306a36Sopenharmony_ci	.type = REGULATOR_VOLTAGE,
3662306a36Sopenharmony_ci	.owner = THIS_MODULE,
3762306a36Sopenharmony_ci	.ops = &dummy_ops,
3862306a36Sopenharmony_ci};
3962306a36Sopenharmony_ci
4062306a36Sopenharmony_cistatic int dummy_regulator_probe(struct platform_device *pdev)
4162306a36Sopenharmony_ci{
4262306a36Sopenharmony_ci	struct regulator_config config = { };
4362306a36Sopenharmony_ci	int ret;
4462306a36Sopenharmony_ci
4562306a36Sopenharmony_ci	config.dev = &pdev->dev;
4662306a36Sopenharmony_ci	config.init_data = &dummy_initdata;
4762306a36Sopenharmony_ci
4862306a36Sopenharmony_ci	dummy_regulator_rdev = devm_regulator_register(&pdev->dev, &dummy_desc,
4962306a36Sopenharmony_ci						       &config);
5062306a36Sopenharmony_ci	if (IS_ERR(dummy_regulator_rdev)) {
5162306a36Sopenharmony_ci		ret = PTR_ERR(dummy_regulator_rdev);
5262306a36Sopenharmony_ci		pr_err("Failed to register regulator: %d\n", ret);
5362306a36Sopenharmony_ci		return ret;
5462306a36Sopenharmony_ci	}
5562306a36Sopenharmony_ci
5662306a36Sopenharmony_ci	return 0;
5762306a36Sopenharmony_ci}
5862306a36Sopenharmony_ci
5962306a36Sopenharmony_cistatic struct platform_driver dummy_regulator_driver = {
6062306a36Sopenharmony_ci	.probe		= dummy_regulator_probe,
6162306a36Sopenharmony_ci	.driver		= {
6262306a36Sopenharmony_ci		.name		= "reg-dummy",
6362306a36Sopenharmony_ci		.probe_type	= PROBE_PREFER_ASYNCHRONOUS,
6462306a36Sopenharmony_ci	},
6562306a36Sopenharmony_ci};
6662306a36Sopenharmony_ci
6762306a36Sopenharmony_cistatic struct platform_device *dummy_pdev;
6862306a36Sopenharmony_ci
6962306a36Sopenharmony_civoid __init regulator_dummy_init(void)
7062306a36Sopenharmony_ci{
7162306a36Sopenharmony_ci	int ret;
7262306a36Sopenharmony_ci
7362306a36Sopenharmony_ci	dummy_pdev = platform_device_alloc("reg-dummy", -1);
7462306a36Sopenharmony_ci	if (!dummy_pdev) {
7562306a36Sopenharmony_ci		pr_err("Failed to allocate dummy regulator device\n");
7662306a36Sopenharmony_ci		return;
7762306a36Sopenharmony_ci	}
7862306a36Sopenharmony_ci
7962306a36Sopenharmony_ci	ret = platform_device_add(dummy_pdev);
8062306a36Sopenharmony_ci	if (ret != 0) {
8162306a36Sopenharmony_ci		pr_err("Failed to register dummy regulator device: %d\n", ret);
8262306a36Sopenharmony_ci		platform_device_put(dummy_pdev);
8362306a36Sopenharmony_ci		return;
8462306a36Sopenharmony_ci	}
8562306a36Sopenharmony_ci
8662306a36Sopenharmony_ci	ret = platform_driver_register(&dummy_regulator_driver);
8762306a36Sopenharmony_ci	if (ret != 0) {
8862306a36Sopenharmony_ci		pr_err("Failed to register dummy regulator driver: %d\n", ret);
8962306a36Sopenharmony_ci		platform_device_unregister(dummy_pdev);
9062306a36Sopenharmony_ci	}
9162306a36Sopenharmony_ci}
92