1 | // SPDX-License-Identifier: GPL-2.0-only |
2 | /* |
3 | * Regulator driver for the Richtek RT5033 |
4 | * |
5 | * Copyright (C) 2014 Samsung Electronics, Co., Ltd. |
6 | * Author: Beomho Seo <beomho.seo@samsung.com> |
7 | */ |
8 | |
9 | #include <linux/module.h> |
10 | #include <linux/platform_device.h> |
11 | #include <linux/regulator/driver.h> |
12 | #include <linux/mfd/rt5033.h> |
13 | #include <linux/mfd/rt5033-private.h> |
14 | #include <linux/regulator/of_regulator.h> |
15 | |
16 | static const struct linear_range rt5033_buck_ranges[] = { |
17 | REGULATOR_LINEAR_RANGE(1000000, 0, 20, 100000), |
18 | REGULATOR_LINEAR_RANGE(3000000, 21, 31, 0), |
19 | }; |
20 | |
21 | static const struct linear_range rt5033_ldo_ranges[] = { |
22 | REGULATOR_LINEAR_RANGE(1200000, 0, 18, 100000), |
23 | REGULATOR_LINEAR_RANGE(3000000, 19, 31, 0), |
24 | }; |
25 | |
26 | static const struct regulator_ops rt5033_safe_ldo_ops = { |
27 | .is_enabled = regulator_is_enabled_regmap, |
28 | .enable = regulator_enable_regmap, |
29 | .disable = regulator_disable_regmap, |
30 | .list_voltage = regulator_list_voltage_linear, |
31 | }; |
32 | |
33 | static const struct regulator_ops rt5033_buck_ops = { |
34 | .is_enabled = regulator_is_enabled_regmap, |
35 | .enable = regulator_enable_regmap, |
36 | .disable = regulator_disable_regmap, |
37 | .list_voltage = regulator_list_voltage_linear_range, |
38 | .get_voltage_sel = regulator_get_voltage_sel_regmap, |
39 | .set_voltage_sel = regulator_set_voltage_sel_regmap, |
40 | }; |
41 | |
42 | static const struct regulator_desc rt5033_supported_regulators[] = { |
43 | [RT5033_BUCK] = { |
44 | .name = "BUCK" , |
45 | .of_match = of_match_ptr("BUCK" ), |
46 | .regulators_node = of_match_ptr("regulators" ), |
47 | .id = RT5033_BUCK, |
48 | .ops = &rt5033_buck_ops, |
49 | .type = REGULATOR_VOLTAGE, |
50 | .owner = THIS_MODULE, |
51 | .n_voltages = RT5033_REGULATOR_BUCK_VOLTAGE_STEP_NUM, |
52 | .linear_ranges = rt5033_buck_ranges, |
53 | .n_linear_ranges = ARRAY_SIZE(rt5033_buck_ranges), |
54 | .enable_reg = RT5033_REG_CTRL, |
55 | .enable_mask = RT5033_CTRL_EN_BUCK_MASK, |
56 | .vsel_reg = RT5033_REG_BUCK_CTRL, |
57 | .vsel_mask = RT5033_BUCK_CTRL_MASK, |
58 | }, |
59 | [RT5033_LDO] = { |
60 | .name = "LDO" , |
61 | .of_match = of_match_ptr("LDO" ), |
62 | .regulators_node = of_match_ptr("regulators" ), |
63 | .id = RT5033_LDO, |
64 | .ops = &rt5033_buck_ops, |
65 | .type = REGULATOR_VOLTAGE, |
66 | .owner = THIS_MODULE, |
67 | .n_voltages = RT5033_REGULATOR_LDO_VOLTAGE_STEP_NUM, |
68 | .linear_ranges = rt5033_ldo_ranges, |
69 | .n_linear_ranges = ARRAY_SIZE(rt5033_ldo_ranges), |
70 | .enable_reg = RT5033_REG_CTRL, |
71 | .enable_mask = RT5033_CTRL_EN_LDO_MASK, |
72 | .vsel_reg = RT5033_REG_LDO_CTRL, |
73 | .vsel_mask = RT5033_LDO_CTRL_MASK, |
74 | }, |
75 | [RT5033_SAFE_LDO] = { |
76 | .name = "SAFE_LDO" , |
77 | .of_match = of_match_ptr("SAFE_LDO" ), |
78 | .regulators_node = of_match_ptr("regulators" ), |
79 | .id = RT5033_SAFE_LDO, |
80 | .ops = &rt5033_safe_ldo_ops, |
81 | .type = REGULATOR_VOLTAGE, |
82 | .owner = THIS_MODULE, |
83 | .n_voltages = 1, |
84 | .min_uV = RT5033_REGULATOR_SAFE_LDO_VOLTAGE, |
85 | .enable_reg = RT5033_REG_CTRL, |
86 | .enable_mask = RT5033_CTRL_EN_SAFE_LDO_MASK, |
87 | }, |
88 | }; |
89 | |
90 | static int rt5033_regulator_probe(struct platform_device *pdev) |
91 | { |
92 | struct rt5033_dev *rt5033 = dev_get_drvdata(dev: pdev->dev.parent); |
93 | int ret, i; |
94 | struct regulator_config config = {}; |
95 | |
96 | config.dev = rt5033->dev; |
97 | config.driver_data = rt5033; |
98 | |
99 | for (i = 0; i < ARRAY_SIZE(rt5033_supported_regulators); i++) { |
100 | struct regulator_dev *regulator; |
101 | |
102 | config.regmap = rt5033->regmap; |
103 | |
104 | regulator = devm_regulator_register(dev: &pdev->dev, |
105 | regulator_desc: &rt5033_supported_regulators[i], config: &config); |
106 | if (IS_ERR(ptr: regulator)) { |
107 | ret = PTR_ERR(ptr: regulator); |
108 | dev_err(&pdev->dev, |
109 | "Regulator init failed %d: with error: %d\n" , |
110 | i, ret); |
111 | return ret; |
112 | } |
113 | } |
114 | |
115 | return 0; |
116 | } |
117 | |
118 | static const struct platform_device_id rt5033_regulator_id[] = { |
119 | { "rt5033-regulator" , }, |
120 | { } |
121 | }; |
122 | MODULE_DEVICE_TABLE(platform, rt5033_regulator_id); |
123 | |
124 | static struct platform_driver rt5033_regulator_driver = { |
125 | .driver = { |
126 | .name = "rt5033-regulator" , |
127 | .probe_type = PROBE_PREFER_ASYNCHRONOUS, |
128 | }, |
129 | .probe = rt5033_regulator_probe, |
130 | .id_table = rt5033_regulator_id, |
131 | }; |
132 | module_platform_driver(rt5033_regulator_driver); |
133 | |
134 | MODULE_DESCRIPTION("Richtek RT5033 Regulator driver" ); |
135 | MODULE_AUTHOR("Beomho Seo <beomho.seo@samsung.com>" ); |
136 | MODULE_LICENSE("GPL" ); |
137 | |