18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * Driver for TPS61050/61052 boost converters, typically used for white LEDs
48c2ecf20Sopenharmony_ci * or audio amplifiers.
58c2ecf20Sopenharmony_ci *
68c2ecf20Sopenharmony_ci * Copyright (C) 2011 ST-Ericsson SA
78c2ecf20Sopenharmony_ci * Written on behalf of Linaro for ST-Ericsson
88c2ecf20Sopenharmony_ci *
98c2ecf20Sopenharmony_ci * Author: Linus Walleij <linus.walleij@linaro.org>
108c2ecf20Sopenharmony_ci */
118c2ecf20Sopenharmony_ci
128c2ecf20Sopenharmony_ci#include <linux/module.h>
138c2ecf20Sopenharmony_ci#include <linux/kernel.h>
148c2ecf20Sopenharmony_ci#include <linux/init.h>
158c2ecf20Sopenharmony_ci#include <linux/err.h>
168c2ecf20Sopenharmony_ci#include <linux/regmap.h>
178c2ecf20Sopenharmony_ci#include <linux/platform_device.h>
188c2ecf20Sopenharmony_ci#include <linux/regulator/driver.h>
198c2ecf20Sopenharmony_ci#include <linux/mfd/core.h>
208c2ecf20Sopenharmony_ci#include <linux/mfd/tps6105x.h>
218c2ecf20Sopenharmony_ci
228c2ecf20Sopenharmony_cistatic const unsigned int tps6105x_voltages[] = {
238c2ecf20Sopenharmony_ci	4500000,
248c2ecf20Sopenharmony_ci	5000000,
258c2ecf20Sopenharmony_ci	5250000,
268c2ecf20Sopenharmony_ci	5000000, /* There is an additional 5V */
278c2ecf20Sopenharmony_ci};
288c2ecf20Sopenharmony_ci
298c2ecf20Sopenharmony_cistatic const struct regulator_ops tps6105x_regulator_ops = {
308c2ecf20Sopenharmony_ci	.enable		= regulator_enable_regmap,
318c2ecf20Sopenharmony_ci	.disable	= regulator_disable_regmap,
328c2ecf20Sopenharmony_ci	.is_enabled	= regulator_is_enabled_regmap,
338c2ecf20Sopenharmony_ci	.get_voltage_sel = regulator_get_voltage_sel_regmap,
348c2ecf20Sopenharmony_ci	.set_voltage_sel = regulator_set_voltage_sel_regmap,
358c2ecf20Sopenharmony_ci	.list_voltage	= regulator_list_voltage_table,
368c2ecf20Sopenharmony_ci};
378c2ecf20Sopenharmony_ci
388c2ecf20Sopenharmony_cistatic const struct regulator_desc tps6105x_regulator_desc = {
398c2ecf20Sopenharmony_ci	.name		= "tps6105x-boost",
408c2ecf20Sopenharmony_ci	.of_match	= of_match_ptr("regulator"),
418c2ecf20Sopenharmony_ci	.ops		= &tps6105x_regulator_ops,
428c2ecf20Sopenharmony_ci	.type		= REGULATOR_VOLTAGE,
438c2ecf20Sopenharmony_ci	.id		= 0,
448c2ecf20Sopenharmony_ci	.owner		= THIS_MODULE,
458c2ecf20Sopenharmony_ci	.n_voltages	= ARRAY_SIZE(tps6105x_voltages),
468c2ecf20Sopenharmony_ci	.volt_table	= tps6105x_voltages,
478c2ecf20Sopenharmony_ci	.vsel_reg	= TPS6105X_REG_0,
488c2ecf20Sopenharmony_ci	.vsel_mask	= TPS6105X_REG0_VOLTAGE_MASK,
498c2ecf20Sopenharmony_ci	.enable_reg	= TPS6105X_REG_0,
508c2ecf20Sopenharmony_ci	.enable_mask	= TPS6105X_REG0_MODE_MASK,
518c2ecf20Sopenharmony_ci	.enable_val	= TPS6105X_REG0_MODE_VOLTAGE <<
528c2ecf20Sopenharmony_ci			  TPS6105X_REG0_MODE_SHIFT,
538c2ecf20Sopenharmony_ci};
548c2ecf20Sopenharmony_ci
558c2ecf20Sopenharmony_ci/*
568c2ecf20Sopenharmony_ci * Registers the chip as a voltage regulator
578c2ecf20Sopenharmony_ci */
588c2ecf20Sopenharmony_cistatic int tps6105x_regulator_probe(struct platform_device *pdev)
598c2ecf20Sopenharmony_ci{
608c2ecf20Sopenharmony_ci	struct tps6105x *tps6105x = dev_get_platdata(&pdev->dev);
618c2ecf20Sopenharmony_ci	struct tps6105x_platform_data *pdata = tps6105x->pdata;
628c2ecf20Sopenharmony_ci	struct regulator_config config = { };
638c2ecf20Sopenharmony_ci	int ret;
648c2ecf20Sopenharmony_ci
658c2ecf20Sopenharmony_ci	/* This instance is not set for regulator mode so bail out */
668c2ecf20Sopenharmony_ci	if (pdata->mode != TPS6105X_MODE_VOLTAGE) {
678c2ecf20Sopenharmony_ci		dev_info(&pdev->dev,
688c2ecf20Sopenharmony_ci			"chip not in voltage mode mode, exit probe\n");
698c2ecf20Sopenharmony_ci		return 0;
708c2ecf20Sopenharmony_ci	}
718c2ecf20Sopenharmony_ci
728c2ecf20Sopenharmony_ci	config.dev = &tps6105x->client->dev;
738c2ecf20Sopenharmony_ci	config.init_data = pdata->regulator_data;
748c2ecf20Sopenharmony_ci	config.driver_data = tps6105x;
758c2ecf20Sopenharmony_ci	config.of_node = pdev->dev.parent->of_node;
768c2ecf20Sopenharmony_ci	config.regmap = tps6105x->regmap;
778c2ecf20Sopenharmony_ci
788c2ecf20Sopenharmony_ci	/* Register regulator with framework */
798c2ecf20Sopenharmony_ci	tps6105x->regulator = devm_regulator_register(&pdev->dev,
808c2ecf20Sopenharmony_ci						      &tps6105x_regulator_desc,
818c2ecf20Sopenharmony_ci						      &config);
828c2ecf20Sopenharmony_ci	if (IS_ERR(tps6105x->regulator)) {
838c2ecf20Sopenharmony_ci		ret = PTR_ERR(tps6105x->regulator);
848c2ecf20Sopenharmony_ci		dev_err(&tps6105x->client->dev,
858c2ecf20Sopenharmony_ci			"failed to register regulator\n");
868c2ecf20Sopenharmony_ci		return ret;
878c2ecf20Sopenharmony_ci	}
888c2ecf20Sopenharmony_ci	platform_set_drvdata(pdev, tps6105x);
898c2ecf20Sopenharmony_ci
908c2ecf20Sopenharmony_ci	return 0;
918c2ecf20Sopenharmony_ci}
928c2ecf20Sopenharmony_ci
938c2ecf20Sopenharmony_cistatic struct platform_driver tps6105x_regulator_driver = {
948c2ecf20Sopenharmony_ci	.driver = {
958c2ecf20Sopenharmony_ci		.name  = "tps6105x-regulator",
968c2ecf20Sopenharmony_ci	},
978c2ecf20Sopenharmony_ci	.probe = tps6105x_regulator_probe,
988c2ecf20Sopenharmony_ci};
998c2ecf20Sopenharmony_ci
1008c2ecf20Sopenharmony_cistatic __init int tps6105x_regulator_init(void)
1018c2ecf20Sopenharmony_ci{
1028c2ecf20Sopenharmony_ci	return platform_driver_register(&tps6105x_regulator_driver);
1038c2ecf20Sopenharmony_ci}
1048c2ecf20Sopenharmony_cisubsys_initcall(tps6105x_regulator_init);
1058c2ecf20Sopenharmony_ci
1068c2ecf20Sopenharmony_cistatic __exit void tps6105x_regulator_exit(void)
1078c2ecf20Sopenharmony_ci{
1088c2ecf20Sopenharmony_ci	platform_driver_unregister(&tps6105x_regulator_driver);
1098c2ecf20Sopenharmony_ci}
1108c2ecf20Sopenharmony_cimodule_exit(tps6105x_regulator_exit);
1118c2ecf20Sopenharmony_ci
1128c2ecf20Sopenharmony_ciMODULE_AUTHOR("Linus Walleij <linus.walleij@linaro.org>");
1138c2ecf20Sopenharmony_ciMODULE_DESCRIPTION("TPS6105x regulator driver");
1148c2ecf20Sopenharmony_ciMODULE_LICENSE("GPL v2");
1158c2ecf20Sopenharmony_ciMODULE_ALIAS("platform:tps6105x-regulator");
116