1 /*
2 * Copyright (c) 2021-2023 Huawei Device Co., Ltd.
3 *
4 * HDF is dual licensed: you can use it either under the terms of
5 * the GPL, or the BSD license, at your option.
6 * See the LICENSE file in the root of this repository for complete details.
7 */
8
9 #include <linux/err.h>
10 #include <linux/kernel.h>
11 #include <linux/device.h>
12 #include <linux/delay.h>
13 #include <linux/platform_device.h>
14 #include <linux/regulator/driver.h>
15 #include <linux/regulator/machine.h>
16 #include <linux/regmap.h>
17 #include <linux/sysfs.h>
18 #include "hdf_log.h"
19 #include "hdf_base.h"
20
21 #define HDF_LOG_TAG regulator_virtual
22
23 #define MINIMUN_VOLTAGE 1000
24 #define MAXIMUN_VOLTAGE 50000
25
26 struct VirtualVoltageRegulatorDev {
27 struct regmap *regmap;
28 struct regulator_dev *dev;
29 };
30
31 // note:linux kernel constraints:len(devName) + len(supplyName) < REG_STR_SIZE(64)
32 static struct regulator_consumer_supply g_virtualVoltageRegulatorVoltSupplies[] = {
33 REGULATOR_SUPPLY("vir-voltage-reg-hdf-adp", "regulator_adapter_consumer01"),
34 };
35
36 // virtual regulator init info
37 static struct regulator_init_data g_virtualVoltageRegulatorInitData = {
38 .constraints = {
39 .name = "virtual_regulator",
40 .min_uV = MINIMUN_VOLTAGE,
41 .max_uV = MAXIMUN_VOLTAGE,
42 .always_on = 1,
43 .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | REGULATOR_CHANGE_STATUS,
44 },
45 .num_consumer_supplies = ARRAY_SIZE(g_virtualVoltageRegulatorVoltSupplies),
46 .consumer_supplies = g_virtualVoltageRegulatorVoltSupplies,
47 };
48
VirtualVoltageRegulatorDevRelease(struct device * dev)49 static void VirtualVoltageRegulatorDevRelease(struct device *dev)
50 {
51 (void)dev;
52 }
53 static struct platform_device g_virtualVoltageRegulatorPlatformDevice = {
54 .name = "virtual_regulator_dev",
55 .id = -1,
56 .dev = {
57 .release = VirtualVoltageRegulatorDevRelease,
58 }
59 };
60
61 enum RegulatorStatus {
62 VIR_REGULATOR_STATUS_OFF,
63 VIR_REGULATOR_STATUS_ON,
64 };
65
66 static int g_virStatus = VIR_REGULATOR_STATUS_OFF;
VirtualVoltageRegulatorEnable(struct regulator_dev * rdev)67 static int VirtualVoltageRegulatorEnable(struct regulator_dev *rdev)
68 {
69 if (rdev == NULL) {
70 HDF_LOGE("VirtualVoltageRegulatorEnable: rdev is null!");
71 return HDF_FAILURE;
72 }
73
74 g_virStatus = VIR_REGULATOR_STATUS_ON;
75 return HDF_SUCCESS;
76 }
77
VirtualVoltageRegulatorDisable(struct regulator_dev * rdev)78 static int VirtualVoltageRegulatorDisable(struct regulator_dev *rdev)
79 {
80 if (rdev == NULL) {
81 HDF_LOGE("VirtualVoltageRegulatorDisable: rdev is null!");
82 return HDF_FAILURE;
83 }
84
85 g_virStatus = VIR_REGULATOR_STATUS_OFF;
86 return HDF_SUCCESS;
87 }
88
VirtualVoltageRegulatorIsEnabled(struct regulator_dev * rdev)89 static int VirtualVoltageRegulatorIsEnabled(struct regulator_dev *rdev)
90 {
91 if (rdev == NULL) {
92 HDF_LOGE("VirtualVoltageRegulatorIsEnabled: rdev is null!");
93 return HDF_FAILURE;
94 }
95
96 return g_virStatus;
97 }
98
VirtualVoltageRegulatorSetVoltage(struct regulator_dev * rdev,int minUv,int maxUv,unsigned * selector)99 static int VirtualVoltageRegulatorSetVoltage(struct regulator_dev *rdev, int minUv,
100 int maxUv, unsigned *selector)
101 {
102 (void)selector;
103 if ((rdev == NULL) || (rdev->constraints == NULL)) {
104 HDF_LOGE("VirtualVoltageRegulatorSetVoltage: rdev or constraints is null!");
105 return HDF_FAILURE;
106 }
107
108 struct regulation_constraints *reguConstraints = rdev->constraints;
109 if (reguConstraints->min_uV == minUv &&
110 reguConstraints->max_uV == maxUv) {
111 return HDF_SUCCESS;
112 }
113
114 return HDF_SUCCESS;
115 }
116
117 #define VIRTUAL_VOLTAGE_VAL_500 500
VirtualVoltageRegulatorGetVoltage(struct regulator_dev * rdev)118 static int VirtualVoltageRegulatorGetVoltage(struct regulator_dev *rdev)
119 {
120 if (rdev == NULL) {
121 HDF_LOGE("VirtualVoltageRegulatorGetVoltage: rdev is null!");
122 return HDF_FAILURE;
123 }
124
125 return VIRTUAL_VOLTAGE_VAL_500;
126 }
127
128 static struct regulator_ops g_virtualVoltageRegulatorOps = {
129 .enable = VirtualVoltageRegulatorEnable,
130 .disable = VirtualVoltageRegulatorDisable,
131 .is_enabled = VirtualVoltageRegulatorIsEnabled,
132 .set_voltage = VirtualVoltageRegulatorSetVoltage,
133 .get_voltage = VirtualVoltageRegulatorGetVoltage,
134 };
135
136 static struct regulator_desc g_virtualVoltageRegulatorDesc = {
137 .name = "regulator_virtual",
138 .type = REGULATOR_VOLTAGE,
139 .ops = &g_virtualVoltageRegulatorOps,
140 .min_uV = MINIMUN_VOLTAGE,
141 .owner = THIS_MODULE,
142 };
143
VirtualVoltageRegulatorPlatformProbe(struct platform_device * platformDev)144 static int VirtualVoltageRegulatorPlatformProbe(struct platform_device *platformDev)
145 {
146 if (platformDev == NULL) {
147 HDF_LOGE("VirtualVoltageRegulatorPlatformProbe: platformDev is null!");
148 return HDF_FAILURE;
149 }
150 struct VirtualVoltageRegulatorDev *data;
151 struct regulator_config config = {0};
152
153 data = devm_kzalloc(&platformDev->dev, sizeof(*data), GFP_KERNEL);
154 if (!data) {
155 return -ENOMEM;
156 }
157
158 config.dev = &platformDev->dev;
159 config.init_data = &g_virtualVoltageRegulatorInitData;
160 config.driver_data = data;
161
162 data->dev = regulator_register(&g_virtualVoltageRegulatorDesc, &config);
163 if (IS_ERR(data->dev)) {
164 HDF_LOGE("VirtualVoltageRegulatorPlatformProbe: fail to register regulator %s\n",
165 g_virtualVoltageRegulatorDesc.name);
166 return PTR_ERR(data->dev);
167 }
168
169 platform_set_drvdata(platformDev, data);
170 HDF_LOGI("VirtualVoltageRegulatorPlatformProbe: success!");
171 return 0;
172 }
173
VirtualVoltageRegulatorPlatformRemove(struct platform_device * platformDev)174 static int VirtualVoltageRegulatorPlatformRemove(struct platform_device *platformDev)
175 {
176 struct VirtualVoltageRegulatorDev *rdev = platform_get_drvdata(platformDev);
177
178 regulator_unregister(rdev->dev);
179
180 platform_set_drvdata(platformDev, NULL);
181 HDF_LOGI("VirtualVoltageRegulatorPlatformRemove: success!");
182 return 0;
183 }
184
185 static struct platform_driver g_virtualVoltageRegulatorPlatformDriver = {
186 .driver = {
187 .name = "virtual_regulator_dev",
188 .owner = THIS_MODULE,
189 },
190 .probe = VirtualVoltageRegulatorPlatformProbe,
191 .remove = VirtualVoltageRegulatorPlatformRemove,
192 };
193
VirtualVoltageRegulatorAdapterInit(void)194 int VirtualVoltageRegulatorAdapterInit(void)
195 {
196 HDF_LOGI("VirtualVoltageRegulatorAdapterInit: enter!");
197 int ret = platform_device_register(&g_virtualVoltageRegulatorPlatformDevice);
198 if (ret == 0) {
199 ret = platform_driver_register(&g_virtualVoltageRegulatorPlatformDriver);
200 } else {
201 HDF_LOGE("VirtualVoltageRegulatorAdapterInit:device register fail, ret: %d!", ret);
202 }
203 return ret;
204 }
205
VirtualVoltageRegulatorInit(void)206 static int __init VirtualVoltageRegulatorInit(void)
207 {
208 HDF_LOGI("VirtualVoltageRegulatorInit: enter!");
209 int ret = platform_device_register(&g_virtualVoltageRegulatorPlatformDevice);
210 if (ret == 0) {
211 ret = platform_driver_register(&g_virtualVoltageRegulatorPlatformDriver);
212 }
213 return ret;
214 }
215
VirtualVoltageRegulatorExit(void)216 static void __exit VirtualVoltageRegulatorExit(void)
217 {
218 HDF_LOGI("VirtualVoltageRegulatorExit: enter!");
219 platform_device_unregister(&g_virtualVoltageRegulatorPlatformDevice);
220 platform_driver_unregister(&g_virtualVoltageRegulatorPlatformDriver);
221 }
222
223 MODULE_DESCRIPTION("Virtual voltage Regulator Controller Platform Device Drivers");
224 MODULE_LICENSE("GPL");
225