1 | // SPDX-License-Identifier: GPL-2.0-only |
2 | /* |
3 | * Driver for TPS61050/61052 boost converters, typically used for white LEDs |
4 | * or audio amplifiers. |
5 | * |
6 | * Copyright (C) 2011 ST-Ericsson SA |
7 | * Written on behalf of Linaro for ST-Ericsson |
8 | * |
9 | * Author: Linus Walleij <linus.walleij@linaro.org> |
10 | */ |
11 | |
12 | #include <linux/module.h> |
13 | #include <linux/kernel.h> |
14 | #include <linux/init.h> |
15 | #include <linux/err.h> |
16 | #include <linux/regmap.h> |
17 | #include <linux/platform_device.h> |
18 | #include <linux/regulator/driver.h> |
19 | #include <linux/mfd/core.h> |
20 | #include <linux/mfd/tps6105x.h> |
21 | |
22 | static const unsigned int tps6105x_voltages[] = { |
23 | 4500000, |
24 | 5000000, |
25 | 5250000, |
26 | 5000000, /* There is an additional 5V */ |
27 | }; |
28 | |
29 | static const struct regulator_ops tps6105x_regulator_ops = { |
30 | .enable = regulator_enable_regmap, |
31 | .disable = regulator_disable_regmap, |
32 | .is_enabled = regulator_is_enabled_regmap, |
33 | .get_voltage_sel = regulator_get_voltage_sel_regmap, |
34 | .set_voltage_sel = regulator_set_voltage_sel_regmap, |
35 | .list_voltage = regulator_list_voltage_table, |
36 | }; |
37 | |
38 | static const struct regulator_desc tps6105x_regulator_desc = { |
39 | .name = "tps6105x-boost" , |
40 | .of_match = of_match_ptr("regulator" ), |
41 | .ops = &tps6105x_regulator_ops, |
42 | .type = REGULATOR_VOLTAGE, |
43 | .id = 0, |
44 | .owner = THIS_MODULE, |
45 | .n_voltages = ARRAY_SIZE(tps6105x_voltages), |
46 | .volt_table = tps6105x_voltages, |
47 | .vsel_reg = TPS6105X_REG_0, |
48 | .vsel_mask = TPS6105X_REG0_VOLTAGE_MASK, |
49 | .enable_reg = TPS6105X_REG_0, |
50 | .enable_mask = TPS6105X_REG0_MODE_MASK, |
51 | .enable_val = TPS6105X_REG0_MODE_VOLTAGE << |
52 | TPS6105X_REG0_MODE_SHIFT, |
53 | }; |
54 | |
55 | /* |
56 | * Registers the chip as a voltage regulator |
57 | */ |
58 | static int tps6105x_regulator_probe(struct platform_device *pdev) |
59 | { |
60 | struct tps6105x *tps6105x = dev_get_platdata(dev: &pdev->dev); |
61 | struct tps6105x_platform_data *pdata = tps6105x->pdata; |
62 | struct regulator_config config = { }; |
63 | int ret; |
64 | |
65 | /* This instance is not set for regulator mode so bail out */ |
66 | if (pdata->mode != TPS6105X_MODE_VOLTAGE) { |
67 | dev_info(&pdev->dev, |
68 | "chip not in voltage mode mode, exit probe\n" ); |
69 | return 0; |
70 | } |
71 | |
72 | config.dev = &tps6105x->client->dev; |
73 | config.init_data = pdata->regulator_data; |
74 | config.driver_data = tps6105x; |
75 | config.of_node = pdev->dev.parent->of_node; |
76 | config.regmap = tps6105x->regmap; |
77 | |
78 | /* Register regulator with framework */ |
79 | tps6105x->regulator = devm_regulator_register(dev: &pdev->dev, |
80 | regulator_desc: &tps6105x_regulator_desc, |
81 | config: &config); |
82 | if (IS_ERR(ptr: tps6105x->regulator)) { |
83 | ret = PTR_ERR(ptr: tps6105x->regulator); |
84 | dev_err(&tps6105x->client->dev, |
85 | "failed to register regulator\n" ); |
86 | return ret; |
87 | } |
88 | platform_set_drvdata(pdev, data: tps6105x); |
89 | |
90 | return 0; |
91 | } |
92 | |
93 | static struct platform_driver tps6105x_regulator_driver = { |
94 | .driver = { |
95 | .name = "tps6105x-regulator" , |
96 | .probe_type = PROBE_PREFER_ASYNCHRONOUS, |
97 | }, |
98 | .probe = tps6105x_regulator_probe, |
99 | }; |
100 | |
101 | static __init int tps6105x_regulator_init(void) |
102 | { |
103 | return platform_driver_register(&tps6105x_regulator_driver); |
104 | } |
105 | subsys_initcall(tps6105x_regulator_init); |
106 | |
107 | static __exit void tps6105x_regulator_exit(void) |
108 | { |
109 | platform_driver_unregister(&tps6105x_regulator_driver); |
110 | } |
111 | module_exit(tps6105x_regulator_exit); |
112 | |
113 | MODULE_AUTHOR("Linus Walleij <linus.walleij@linaro.org>" ); |
114 | MODULE_DESCRIPTION("TPS6105x regulator driver" ); |
115 | MODULE_LICENSE("GPL v2" ); |
116 | MODULE_ALIAS("platform:tps6105x-regulator" ); |
117 | |