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, \ | |
45 | .fixed_uV = SM5703_USBLDO_MICROVOLT, \ | |
46 | .enable_reg = SM5703_REG_USBLDO12, \ | |
47 | .enable_mask = SM5703_REG_EN_USBLDO ##_id, \ | |
48 | .owner = THIS_MODULE, \ | |
49 | } | |
50 | ||
51 | #define SM5703VBUS(_name) \ | |
52 | [SM5703_VBUS] = { \ | |
53 | .name = _name, \ | |
54 | .of_match = _name, \ | |
55 | .regulators_node = "regulators", \ | |
56 | .type = REGULATOR_VOLTAGE, \ | |
57 | .id = SM5703_VBUS, \ | |
58 | .ops = &sm5703_regulator_ops_fixed, \ | |
59 | .fixed_uV = SM5703_VBUS_MICROVOLT, \ | |
60 | .enable_reg = SM5703_REG_CNTL, \ | |
61 | .enable_mask = SM5703_OPERATION_MODE_MASK, \ | |
62 | .enable_val = SM5703_OPERATION_MODE_USB_OTG_MODE, \ | |
63 | .disable_val = SM5703_OPERATION_MODE_CHARGING_ON, \ | |
64 | .owner = THIS_MODULE, \ | |
65 | } | |
66 | ||
67 | #define SM5703BUCK(_name) \ | |
68 | [SM5703_BUCK] = { \ | |
69 | .name = _name, \ | |
70 | .of_match = _name, \ | |
71 | .regulators_node = "regulators", \ | |
72 | .type = REGULATOR_VOLTAGE, \ | |
73 | .id = SM5703_BUCK, \ | |
74 | .ops = &sm5703_regulator_ops, \ | |
75 | .n_voltages = ARRAY_SIZE(sm5703_buck_voltagemap), \ | |
76 | .volt_table = sm5703_buck_voltagemap, \ | |
77 | .vsel_reg = SM5703_REG_BUCK, \ | |
78 | .vsel_mask = SM5703_BUCK_VOLT_MASK, \ | |
79 | .enable_reg = SM5703_REG_BUCK, \ | |
80 | .enable_mask = SM5703_REG_EN_BUCK, \ | |
81 | .owner = THIS_MODULE, \ | |
82 | } | |
83 | ||
84 | #define SM5703LDO(_name, _id) \ | |
85 | [SM5703_LDO ## _id] = { \ | |
86 | .name = _name, \ | |
87 | .of_match = _name, \ | |
88 | .regulators_node = "regulators", \ | |
89 | .type = REGULATOR_VOLTAGE, \ | |
90 | .id = SM5703_LDO ## _id, \ | |
91 | .ops = &sm5703_regulator_ops, \ | |
92 | .n_voltages = ARRAY_SIZE(sm5703_ldo_voltagemap), \ | |
93 | .volt_table = sm5703_ldo_voltagemap, \ | |
94 | .vsel_reg = SM5703_REG_LDO ##_id, \ | |
95 | .vsel_mask = SM5703_LDO_VOLT_MASK, \ | |
96 | .enable_reg = SM5703_REG_LDO ##_id, \ | |
97 | .enable_mask = SM5703_LDO_EN, \ | |
98 | .owner = THIS_MODULE, \ | |
99 | } | |
100 | ||
101 | static const struct regulator_ops sm5703_regulator_ops = { | |
102 | .enable = regulator_enable_regmap, | |
103 | .disable = regulator_disable_regmap, | |
104 | .is_enabled = regulator_is_enabled_regmap, | |
105 | .list_voltage = regulator_list_voltage_table, | |
106 | .get_voltage_sel = regulator_get_voltage_sel_regmap, | |
107 | .set_voltage_sel = regulator_set_voltage_sel_regmap, | |
108 | }; | |
109 | ||
110 | static const struct regulator_ops sm5703_regulator_ops_fixed = { | |
111 | .enable = regulator_enable_regmap, | |
112 | .disable = regulator_disable_regmap, | |
113 | .is_enabled = regulator_is_enabled_regmap, | |
114 | }; | |
115 | ||
116 | static struct regulator_desc sm5703_regulators_desc[SM5703_MAX_REGULATORS] = { | |
117 | SM5703BUCK("buck"), | |
118 | SM5703LDO("ldo1", 1), | |
119 | SM5703LDO("ldo2", 2), | |
120 | SM5703LDO("ldo3", 3), | |
121 | SM5703USBLDO("usbldo1", 1), | |
122 | SM5703USBLDO("usbldo2", 2), | |
123 | SM5703VBUS("vbus"), | |
124 | }; | |
125 | ||
126 | static int sm5703_regulator_probe(struct platform_device *pdev) | |
127 | { | |
128 | struct device *dev = &pdev->dev; | |
129 | struct regulator_config config = { NULL, }; | |
130 | struct regulator_dev *rdev; | |
131 | struct sm5703_dev *sm5703 = dev_get_drvdata(pdev->dev.parent); | |
132 | int i; | |
133 | ||
134 | config.dev = dev->parent; | |
135 | config.regmap = sm5703->regmap; | |
136 | ||
137 | for (i = 0; i < SM5703_MAX_REGULATORS; i++) { | |
138 | rdev = devm_regulator_register(dev, | |
139 | &sm5703_regulators_desc[i], | |
140 | &config); | |
141 | if (IS_ERR(rdev)) | |
142 | return dev_err_probe(dev, PTR_ERR(rdev), | |
143 | "Failed to register a regulator\n"); | |
144 | } | |
145 | ||
146 | return 0; | |
147 | } | |
148 | ||
149 | static const struct platform_device_id sm5703_regulator_id[] = { | |
150 | { "sm5703-regulator", 0 }, | |
151 | {} | |
152 | }; | |
153 | MODULE_DEVICE_TABLE(platform, sm5703_regulator_id); | |
154 | ||
155 | static struct platform_driver sm5703_regulator_driver = { | |
156 | .driver = { | |
157 | .name = "sm5703-regulator", | |
158 | }, | |
159 | .probe = sm5703_regulator_probe, | |
160 | .id_table = sm5703_regulator_id, | |
161 | }; | |
162 | ||
163 | module_platform_driver(sm5703_regulator_driver); | |
164 | ||
165 | MODULE_DESCRIPTION("Silicon Mitus SM5703 LDO/Buck/USB regulator driver"); | |
166 | MODULE_AUTHOR("Markuss Broks <markuss.broks@gmail.com>"); | |
167 | MODULE_LICENSE("GPL"); |