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