Commit | Line | Data |
---|---|---|
e8858ba8 MB |
1 | // SPDX-License-Identifier: GPL-2.0-only |
2 | ||
3 | #include <linux/mfd/sm5703.h> | |
4 | #include <linux/module.h> | |
5 | #include <linux/mod_devicetable.h> | |
6 | #include <linux/platform_device.h> | |
7 | #include <linux/regmap.h> | |
8 | #include <linux/regulator/driver.h> | |
9 | #include <linux/regulator/of_regulator.h> | |
10 | ||
11 | enum sm5703_regulators { | |
12 | SM5703_BUCK, | |
13 | SM5703_LDO1, | |
14 | SM5703_LDO2, | |
15 | SM5703_LDO3, | |
16 | SM5703_USBLDO1, | |
17 | SM5703_USBLDO2, | |
18 | SM5703_VBUS, | |
19 | SM5703_MAX_REGULATORS, | |
20 | }; | |
21 | ||
22 | static const int sm5703_ldo_voltagemap[] = { | |
23 | 1500000, 1800000, 2600000, 2800000, 3000000, 3300000, | |
24 | }; | |
25 | ||
26 | static const int sm5703_buck_voltagemap[] = { | |
27 | 1000000, 1000000, 1000000, 1000000, | |
28 | 1000000, 1000000, 1000000, 1000000, | |
29 | 1000000, 1000000, 1000000, 1100000, | |
30 | 1200000, 1300000, 1400000, 1500000, | |
31 | 1600000, 1700000, 1800000, 1900000, | |
32 | 2000000, 2100000, 2200000, 2300000, | |
33 | 2400000, 2500000, 2600000, 2700000, | |
34 | 2800000, 2900000, 3000000, 3000000, | |
35 | }; | |
36 | ||
37 | #define SM5703USBLDO(_name, _id) \ | |
38 | [SM5703_USBLDO ## _id] = { \ | |
39 | .name = _name, \ | |
40 | .of_match = _name, \ | |
41 | .regulators_node = "regulators", \ | |
42 | .type = REGULATOR_VOLTAGE, \ | |
43 | .id = SM5703_USBLDO ## _id, \ | |
44 | .ops = &sm5703_regulator_ops_fixed, \ | |
7c750406 | 45 | .n_voltages = 1, \ |
e8858ba8 MB |
46 | .fixed_uV = SM5703_USBLDO_MICROVOLT, \ |
47 | .enable_reg = SM5703_REG_USBLDO12, \ | |
48 | .enable_mask = SM5703_REG_EN_USBLDO ##_id, \ | |
49 | .owner = THIS_MODULE, \ | |
50 | } | |
51 | ||
52 | #define SM5703VBUS(_name) \ | |
53 | [SM5703_VBUS] = { \ | |
54 | .name = _name, \ | |
55 | .of_match = _name, \ | |
56 | .regulators_node = "regulators", \ | |
57 | .type = REGULATOR_VOLTAGE, \ | |
58 | .id = SM5703_VBUS, \ | |
59 | .ops = &sm5703_regulator_ops_fixed, \ | |
7c750406 | 60 | .n_voltages = 1, \ |
e8858ba8 MB |
61 | .fixed_uV = SM5703_VBUS_MICROVOLT, \ |
62 | .enable_reg = SM5703_REG_CNTL, \ | |
63 | .enable_mask = SM5703_OPERATION_MODE_MASK, \ | |
64 | .enable_val = SM5703_OPERATION_MODE_USB_OTG_MODE, \ | |
65 | .disable_val = SM5703_OPERATION_MODE_CHARGING_ON, \ | |
66 | .owner = THIS_MODULE, \ | |
67 | } | |
68 | ||
69 | #define SM5703BUCK(_name) \ | |
70 | [SM5703_BUCK] = { \ | |
71 | .name = _name, \ | |
72 | .of_match = _name, \ | |
73 | .regulators_node = "regulators", \ | |
74 | .type = REGULATOR_VOLTAGE, \ | |
75 | .id = SM5703_BUCK, \ | |
76 | .ops = &sm5703_regulator_ops, \ | |
77 | .n_voltages = ARRAY_SIZE(sm5703_buck_voltagemap), \ | |
78 | .volt_table = sm5703_buck_voltagemap, \ | |
79 | .vsel_reg = SM5703_REG_BUCK, \ | |
80 | .vsel_mask = SM5703_BUCK_VOLT_MASK, \ | |
81 | .enable_reg = SM5703_REG_BUCK, \ | |
82 | .enable_mask = SM5703_REG_EN_BUCK, \ | |
83 | .owner = THIS_MODULE, \ | |
84 | } | |
85 | ||
86 | #define SM5703LDO(_name, _id) \ | |
87 | [SM5703_LDO ## _id] = { \ | |
88 | .name = _name, \ | |
89 | .of_match = _name, \ | |
90 | .regulators_node = "regulators", \ | |
91 | .type = REGULATOR_VOLTAGE, \ | |
92 | .id = SM5703_LDO ## _id, \ | |
93 | .ops = &sm5703_regulator_ops, \ | |
94 | .n_voltages = ARRAY_SIZE(sm5703_ldo_voltagemap), \ | |
95 | .volt_table = sm5703_ldo_voltagemap, \ | |
96 | .vsel_reg = SM5703_REG_LDO ##_id, \ | |
97 | .vsel_mask = SM5703_LDO_VOLT_MASK, \ | |
98 | .enable_reg = SM5703_REG_LDO ##_id, \ | |
99 | .enable_mask = SM5703_LDO_EN, \ | |
100 | .owner = THIS_MODULE, \ | |
101 | } | |
102 | ||
103 | static const struct regulator_ops sm5703_regulator_ops = { | |
104 | .enable = regulator_enable_regmap, | |
105 | .disable = regulator_disable_regmap, | |
106 | .is_enabled = regulator_is_enabled_regmap, | |
107 | .list_voltage = regulator_list_voltage_table, | |
108 | .get_voltage_sel = regulator_get_voltage_sel_regmap, | |
109 | .set_voltage_sel = regulator_set_voltage_sel_regmap, | |
110 | }; | |
111 | ||
112 | static const struct regulator_ops sm5703_regulator_ops_fixed = { | |
113 | .enable = regulator_enable_regmap, | |
114 | .disable = regulator_disable_regmap, | |
115 | .is_enabled = regulator_is_enabled_regmap, | |
116 | }; | |
117 | ||
118 | static struct regulator_desc sm5703_regulators_desc[SM5703_MAX_REGULATORS] = { | |
119 | SM5703BUCK("buck"), | |
120 | SM5703LDO("ldo1", 1), | |
121 | SM5703LDO("ldo2", 2), | |
122 | SM5703LDO("ldo3", 3), | |
123 | SM5703USBLDO("usbldo1", 1), | |
124 | SM5703USBLDO("usbldo2", 2), | |
125 | SM5703VBUS("vbus"), | |
126 | }; | |
127 | ||
128 | static int sm5703_regulator_probe(struct platform_device *pdev) | |
129 | { | |
130 | struct device *dev = &pdev->dev; | |
131 | struct regulator_config config = { NULL, }; | |
132 | struct regulator_dev *rdev; | |
133 | struct sm5703_dev *sm5703 = dev_get_drvdata(pdev->dev.parent); | |
134 | int i; | |
135 | ||
136 | config.dev = dev->parent; | |
137 | config.regmap = sm5703->regmap; | |
138 | ||
139 | for (i = 0; i < SM5703_MAX_REGULATORS; i++) { | |
140 | rdev = devm_regulator_register(dev, | |
141 | &sm5703_regulators_desc[i], | |
142 | &config); | |
143 | if (IS_ERR(rdev)) | |
144 | return dev_err_probe(dev, PTR_ERR(rdev), | |
145 | "Failed to register a regulator\n"); | |
146 | } | |
147 | ||
148 | return 0; | |
149 | } | |
150 | ||
151 | static const struct platform_device_id sm5703_regulator_id[] = { | |
152 | { "sm5703-regulator", 0 }, | |
153 | {} | |
154 | }; | |
155 | MODULE_DEVICE_TABLE(platform, sm5703_regulator_id); | |
156 | ||
157 | static struct platform_driver sm5703_regulator_driver = { | |
158 | .driver = { | |
159 | .name = "sm5703-regulator", | |
41cff178 | 160 | .probe_type = PROBE_PREFER_ASYNCHRONOUS, |
e8858ba8 MB |
161 | }, |
162 | .probe = sm5703_regulator_probe, | |
163 | .id_table = sm5703_regulator_id, | |
164 | }; | |
165 | ||
166 | module_platform_driver(sm5703_regulator_driver); | |
167 | ||
168 | MODULE_DESCRIPTION("Silicon Mitus SM5703 LDO/Buck/USB regulator driver"); | |
169 | MODULE_AUTHOR("Markuss Broks <markuss.broks@gmail.com>"); | |
170 | MODULE_LICENSE("GPL"); |