1 /*
2 * Copyright (c) 2022-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 "device_resource_if.h"
10 #include "hdf_log.h"
11 #include "osal_io.h"
12 #include "osal_mem.h"
13 #include "pwm/pwm_core.h"
14
15 #define HDF_LOG_TAG pwm_virtual
16 #define PWM_DEFAULT_PERIOD 0x3E7
17 #define PWM_DEFAULT_POLARITY 0
18 #define PWM_DEFAULT_DUTY_CYCLE 0x14D
19 #define PWM_MIN_PERIOD 666
20
21 struct VirtualPwm {
22 struct PwmDev dev;
23 bool supportPolarity;
24 };
25
VirtualPwmDeviceGet(struct PwmDev * pwm)26 int32_t VirtualPwmDeviceGet(struct PwmDev *pwm)
27 {
28 if (pwm == NULL) {
29 HDF_LOGE("VirtualPwmDeviceGet: pwm is null!");
30 return HDF_ERR_INVALID_OBJECT;
31 }
32
33 return HDF_SUCCESS;
34 }
VirtualPwmDevicePut(struct PwmDev * pwm)35 int32_t VirtualPwmDevicePut(struct PwmDev *pwm)
36 {
37 if (pwm == NULL) {
38 HDF_LOGE("VirtualPwmDevicePut: pwm is null!");
39 return HDF_ERR_INVALID_OBJECT;
40 }
41
42 return HDF_SUCCESS;
43 }
44
VirtualPwmSetConfig(struct PwmDev * pwm,struct PwmConfig * config)45 int32_t VirtualPwmSetConfig(struct PwmDev *pwm, struct PwmConfig *config)
46 {
47 if (pwm == NULL || config == NULL) {
48 HDF_LOGE("VirtualPwmSetConfig: pwm or config is null!");
49 return HDF_ERR_INVALID_PARAM;
50 }
51 if (config->polarity != PWM_NORMAL_POLARITY && config->polarity != PWM_INVERTED_POLARITY) {
52 HDF_LOGE("VirtualPwmSetConfig: polarity %hhu is invalid!", config->polarity);
53 return HDF_ERR_INVALID_PARAM;
54 }
55 if (config->period < PWM_MIN_PERIOD) {
56 HDF_LOGE("VirtualPwmSetConfig: period %u is not support, min period %d!", config->period, PWM_MIN_PERIOD);
57 return HDF_ERR_INVALID_PARAM;
58 }
59 if (config->duty < 1 || config->duty > config->period) {
60 HDF_LOGE("VirtualPwmSetConfig: duty %u is not support, duty must in [1, period = %u]!",
61 config->duty, config->period);
62 return HDF_ERR_INVALID_PARAM;
63 }
64 pwm->cfg = *config;
65
66 return HDF_SUCCESS;
67 }
68 static struct PwmMethod g_method = {
69 .setConfig = VirtualPwmSetConfig,
70 .open = VirtualPwmDeviceGet,
71 .close = VirtualPwmDevicePut,
72 };
73
VirtualPwmProbe(struct VirtualPwm * virtual,struct HdfDeviceObject * obj)74 static int32_t VirtualPwmProbe(struct VirtualPwm *virtual, struct HdfDeviceObject *obj)
75 {
76 struct DeviceResourceIface *iface = NULL;
77
78 iface = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
79 if (iface == NULL || iface->GetUint32 == NULL) {
80 HDF_LOGE("VirtualPwmProbe: face is invalid!");
81 return HDF_FAILURE;
82 }
83
84 if (iface->GetUint32(obj->property, "num", &(virtual->dev.num), 0) != HDF_SUCCESS) {
85 HDF_LOGE("VirtualPwmProbe: read num fail!");
86 return HDF_FAILURE;
87 }
88
89 virtual->supportPolarity = true;
90 virtual->dev.method = &g_method;
91 virtual->dev.cfg.duty = PWM_DEFAULT_DUTY_CYCLE;
92 virtual->dev.cfg.period = PWM_DEFAULT_PERIOD;
93 virtual->dev.cfg.polarity = PWM_DEFAULT_POLARITY;
94 virtual->dev.cfg.status = PWM_DISABLE_STATUS;
95 virtual->dev.cfg.number = virtual->dev.num;
96 virtual->dev.busy = false;
97 if (PwmDeviceAdd(obj, &(virtual->dev)) != HDF_SUCCESS) {
98 HDF_LOGE("VirtualPwmProbe: [PwmDeviceAdd] fail!");
99 return HDF_FAILURE;
100 }
101 HDF_LOGI("VirtualPwmProbe: set PwmConfig: number %u, period %u, duty %u, polarity %hhu, enable %hhu!",
102 virtual->dev.cfg.number, virtual->dev.cfg.period, virtual->dev.cfg.duty,
103 virtual->dev.cfg.polarity, virtual->dev.cfg.status);
104 return HDF_SUCCESS;
105 }
106
VirtualPwmBind(struct HdfDeviceObject * obj)107 static int32_t VirtualPwmBind(struct HdfDeviceObject *obj)
108 {
109 (void)obj;
110 return HDF_SUCCESS;
111 }
112
VirtualPwmInit(struct HdfDeviceObject * obj)113 static int32_t VirtualPwmInit(struct HdfDeviceObject *obj)
114 {
115 int ret;
116 struct VirtualPwm *virtual = NULL;
117
118 if (obj == NULL) {
119 HDF_LOGE("VirtualPwmInit: obj is null!");
120 return HDF_ERR_INVALID_OBJECT;
121 }
122 virtual = (struct VirtualPwm *)OsalMemCalloc(sizeof(*virtual));
123 if (virtual == NULL) {
124 HDF_LOGE("VirtualPwmInit: OsalMemCalloc virtual error!");
125 return HDF_ERR_MALLOC_FAIL;
126 }
127
128 ret = VirtualPwmProbe(virtual, obj);
129 if (ret != HDF_SUCCESS) {
130 HDF_LOGE("VirtualPwmInit: error probe, ret is %d!", ret);
131 OsalMemFree(virtual);
132 return ret;
133 }
134 HDF_LOGI("VirtualPwmInit: pwm init success!");
135 return ret;
136 }
137
VirtualPwmRelease(struct HdfDeviceObject * obj)138 static void VirtualPwmRelease(struct HdfDeviceObject *obj)
139 {
140 struct VirtualPwm *virtual = NULL;
141
142 if (obj == NULL) {
143 HDF_LOGE("VirtualPwmRelease: obj is null!");
144 return;
145 }
146 virtual = (struct VirtualPwm *)obj->service;
147 if (virtual == NULL) {
148 HDF_LOGE("VirtualPwmRelease: virtual is null!");
149 return;
150 }
151 PwmDeviceRemove(obj, &(virtual->dev));
152 OsalMemFree(virtual);
153 }
154
155 struct HdfDriverEntry g_virtualPwm = {
156 .moduleVersion = 1,
157 .moduleName = "virtual_pwm_driver",
158 .Bind = VirtualPwmBind,
159 .Init = VirtualPwmInit,
160 .Release = VirtualPwmRelease,
161 };
162
163 HDF_INIT(g_virtualPwm);
164