1 /*
2 * Copyright (c) 2022 Jiangsu Hoperun Software Co., Ltd.
3 *
4 * This file 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 <stdlib.h>
10 #include <stdio.h>
11 #include "device_resource_if.h"
12 #include "hdf_device_desc.h"
13 #include "pwm_core.h"
14 #include "hdf_log.h"
15 #include "wm_pwm.h"
16
17 struct PwmResource {
18 uint32_t channel;
19 uint32_t freq;
20 };
21
22 struct PwmDevice {
23 struct IDeviceIoService ioService;
24 pwm_init_param pwmCfg;
25 struct PwmConfig *cfg;
26 struct PwmResource resource;
27 };
28
29 static int32_t PwmDevSetConfig(struct PwmDev *pwm, struct PwmConfig *config);
30
31 struct PwmMethod g_pwmmethod = {
32 .setConfig = PwmDevSetConfig,
33 };
34
PwmDevSetConfig(struct PwmDev * pwm,struct PwmConfig * config)35 static int32_t PwmDevSetConfig(struct PwmDev *pwm, struct PwmConfig *config)
36 {
37 struct PwmDevice *prvPwm = NULL;
38 pwm_init_param *pwmCfg = NULL;
39 uint32_t freq;
40
41 if (pwm == NULL || config == NULL) {
42 HDF_LOGE("%s\r\n", __FUNCTION__);
43 return HDF_FAILURE;
44 }
45
46 prvPwm = (struct PwmDevice *)PwmGetPriv(pwm);
47 if (prvPwm == NULL) {
48 return HDF_FAILURE;
49 }
50 pwmCfg = &prvPwm->pwmCfg;
51 pwmCfg->period = config->period;
52 pwmCfg->duty = config->duty;
53 pwmCfg->pnum = config->number;
54 pwmCfg->channel = prvPwm->resource.channel;
55 freq = prvPwm->resource.freq;
56
57 if (config->status == PWM_ENABLE_STATUS) {
58 tls_pwm_init(pwmCfg->channel, freq, pwmCfg->duty, pwmCfg->pnum);
59 }
60
61 return HDF_SUCCESS;
62 }
63
GetPwmDeviceResource(struct PwmDevice * device,const struct DeviceResourceNode * resourceNode)64 static uint32_t GetPwmDeviceResource(
65 struct PwmDevice *device, const struct DeviceResourceNode *resourceNode)
66 {
67 struct DeviceResourceIface *dri = NULL;
68 struct PwmResource *resource = NULL;
69 if (device == NULL || resourceNode == NULL) {
70 HDF_LOGE("resource or device is NULL\r\n");
71 return HDF_ERR_INVALID_PARAM;
72 }
73
74 resource = &device->resource;
75 if (resource == NULL) {
76 HDF_LOGE("resource is NULL\r\n");
77 return HDF_ERR_INVALID_OBJECT;
78 }
79
80 dri = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
81 if (dri == NULL || dri->GetUint32 == NULL) {
82 HDF_LOGE("DeviceResourceIface is invalid\r\n");
83 return HDF_ERR_INVALID_PARAM;
84 }
85
86 if (dri->GetUint32(resourceNode, "channel", &resource->channel, 0) != HDF_SUCCESS) {
87 HDF_LOGE("read channel fail\r\n");
88 return HDF_FAILURE;
89 }
90
91 if (dri->GetUint32(resourceNode, "freq", &resource->freq, 0) != HDF_SUCCESS) {
92 HDF_LOGE("read freq fail\r\n");
93 return HDF_FAILURE;
94 }
95
96 return HDF_SUCCESS;
97 }
98
AttachPwmDevice(struct PwmDev * host,const struct HdfDeviceObject * device)99 static int32_t AttachPwmDevice(struct PwmDev *host, const struct HdfDeviceObject *device)
100 {
101 int32_t ret;
102 struct PwmDevice *pwmDevice = NULL;
103 if (device == NULL || device->property == NULL || host == NULL) {
104 HDF_LOGE("%s: param is NULL\r\n", __func__);
105 return HDF_ERR_INVALID_PARAM;
106 }
107
108 pwmDevice = (struct PwmDevice *)OsalMemAlloc(sizeof(struct PwmDevice));
109 if (pwmDevice == NULL) {
110 HDF_LOGE("%s: OsalMemAlloc pwmDevice error\r\n", __func__);
111 return HDF_ERR_MALLOC_FAIL;
112 }
113
114 ret = GetPwmDeviceResource(pwmDevice, device->property);
115 if (ret != HDF_SUCCESS) {
116 (void)OsalMemFree(pwmDevice);
117 return HDF_FAILURE;
118 }
119
120 host->priv = pwmDevice;
121
122 return HDF_SUCCESS;
123 }
124
PwmDriverBind(struct HdfDeviceObject * device)125 static int32_t PwmDriverBind(struct HdfDeviceObject *device)
126 {
127 static struct PwmDev devService;
128
129 if (device == NULL) {
130 HDF_LOGE("hdfDevice object is null!\r\n");
131 return HDF_FAILURE;
132 }
133
134 device->service = &devService.service;
135 devService.device = device;
136 HDF_LOGI("Enter %s\r\n", __func__);
137
138 return HDF_SUCCESS;
139 }
140
PwmDriverInit(struct HdfDeviceObject * device)141 static int32_t PwmDriverInit(struct HdfDeviceObject *device)
142 {
143 int32_t ret;
144 struct PwmDev *host = NULL;
145
146 if (device == NULL) {
147 HDF_LOGE("%s: device is NULL\r\n", __func__);
148 return HDF_ERR_INVALID_OBJECT;
149 }
150
151 HDF_LOGI("Enter %s:\r\n", __func__);
152
153 host = (struct PwmDev *)OsalMemAlloc(sizeof(struct PwmDev));
154 if (host == NULL) {
155 HDF_LOGE("%s: host is NULL\r\n", __func__);
156 return HDF_ERR_MALLOC_FAIL;
157 }
158
159 ret = AttachPwmDevice(host, device);
160 if (ret != HDF_SUCCESS) {
161 OsalMemFree(host);
162 HDF_LOGE("%s:attach error\r\n", __func__);
163 return HDF_DEV_ERR_ATTACHDEV_FAIL;
164 }
165
166 host->method = &g_pwmmethod;
167 ret = PwmDeviceAdd(device, host);
168 if (ret != HDF_SUCCESS) {
169 PwmDeviceRemove(device, host);
170 OsalMemFree(host->device);
171 OsalMemFree(host);
172 return HDF_DEV_ERR_NO_DEVICE;
173 }
174
175 HDF_LOGI("PwmDriverInit success!\r\n");
176 return HDF_SUCCESS;
177 }
178
PwmDriverRelease(struct HdfDeviceObject * device)179 static void PwmDriverRelease(struct HdfDeviceObject *device)
180 {
181 struct PwmDev *host = NULL;
182
183 if (device == NULL || device->service == NULL) {
184 HDF_LOGE("device is null\r\n");
185 return;
186 }
187
188 host = (struct PwmDev *)device->service;
189 if (host->device != NULL) {
190 host->method = NULL;
191 OsalMemFree(host->device);
192 OsalMemFree(host);
193 host->device = NULL;
194 host = NULL;
195 }
196
197 device->service = NULL;
198 HDF_LOGI("PwmDriverRelease finish!!\r\n");
199 return;
200 }
201
202 /* HdfDriverEntry definitions */
203 struct HdfDriverEntry g_pwmDriverEntry = {
204 .moduleVersion = 1,
205 .moduleName = "WM_PWM_MODULE_HDF",
206 .Bind = PwmDriverBind,
207 .Init = PwmDriverInit,
208 .Release = PwmDriverRelease,
209 };
210
211 // Initialize HdfDriverEntry
212 HDF_INIT(g_pwmDriverEntry);
213