1 /*
2 * pwm_adapter.c
3 *
4 * pwm driver adapter of linux
5 *
6 * Copyright (c) 2020-2021 Huawei Device Co., Ltd.
7 *
8 * This software is licensed under the terms of the GNU General Public
9 * License version 2, as published by the Free Software Foundation, and
10 * may be copied, distributed, and modified under those terms.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 */
18
19 #include <linux/pwm.h>
20 #include "device_resource_if.h"
21 #include "hdf_log.h"
22 #include "osal_mem.h"
23 #include "pwm_core.h"
24
25 #define HDF_LOG_TAG pwm_adapter
26
HdfPwmOpen(struct PwmDev * pwm)27 int32_t HdfPwmOpen(struct PwmDev *pwm)
28 {
29 struct pwm_device *device = NULL;
30
31 if (pwm == NULL) {
32 HDF_LOGE("%s: pwm is null", __func__);
33 return HDF_ERR_INVALID_PARAM;
34 }
35 device = pwm_request(pwm->num, NULL);
36 if (IS_ERR(device)) {
37 HDF_LOGE("%s: pwm_request pwm%d fail", __func__, pwm->num);
38 return HDF_FAILURE;
39 }
40 pwm->cfg.period = device->state.period;
41 pwm->cfg.duty = device->state.duty_cycle;
42 pwm->cfg.polarity = device->state.polarity;
43 pwm->cfg.status = device->state.enabled ? PWM_ENABLE_STATUS : PWM_DISABLE_STATUS;
44 pwm->priv = device;
45 return HDF_SUCCESS;
46 }
47
HdfPwmClose(struct PwmDev * pwm)48 int32_t HdfPwmClose(struct PwmDev *pwm)
49 {
50 if (pwm == NULL) {
51 HDF_LOGE("%s: pwm is null", __func__);
52 return HDF_ERR_INVALID_PARAM;
53 }
54 pwm_free((struct pwm_device *)pwm->priv);
55 return HDF_SUCCESS;
56 }
57
HdfPwmSetConfig(struct PwmDev * pwm,struct PwmConfig * config)58 int32_t HdfPwmSetConfig(struct PwmDev *pwm, struct PwmConfig *config)
59 {
60 int32_t ret;
61 struct pwm_state state;
62
63 if (pwm == NULL || pwm->priv == NULL || config == NULL) {
64 HDF_LOGE("%s: hp reg or config is null", __func__);
65 return HDF_ERR_INVALID_PARAM;
66 }
67
68 state.duty_cycle = config->duty;
69 state.enabled = (config->status == PWM_ENABLE_STATUS) ? true : false;
70 state.period = config->period;
71 state.polarity = config->polarity;
72 HDF_LOGI("%s: set PwmConfig: number %u, period %u, duty %u, polarity %u, enable %u.",
73 __func__, config->number, config->period, config->duty, config->polarity, config->status);
74 ret = pwm_apply_state(pwm->priv, &state);
75 if (ret < 0) {
76 HDF_LOGE("%s: [pwm_apply_state] failed.", __func__);
77 return HDF_FAILURE;
78 }
79 HDF_LOGI("%s: success.", __func__);
80 return HDF_SUCCESS;
81 }
82
83 struct PwmMethod g_pwmOps = {
84 .setConfig = HdfPwmSetConfig,
85 .open = HdfPwmOpen,
86 .close = HdfPwmClose,
87 };
88
HdfPwmBind(struct HdfDeviceObject * obj)89 static int32_t HdfPwmBind(struct HdfDeviceObject *obj)
90 {
91 (void)obj;
92 return HDF_SUCCESS;
93 }
94
HdfPwmInit(struct HdfDeviceObject * obj)95 static int32_t HdfPwmInit(struct HdfDeviceObject *obj)
96 {
97 int32_t ret;
98 uint32_t num;
99 struct PwmDev *pwm = NULL;
100 struct DeviceResourceIface *iface = NULL;
101
102 HDF_LOGI("%s: entry", __func__);
103 if (obj == NULL) {
104 HDF_LOGE("%s: obj is null", __func__);
105 return HDF_ERR_INVALID_OBJECT;
106 }
107 iface = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
108 if (iface == NULL || iface->GetUint32 == NULL) {
109 HDF_LOGE("%s: face is invalid", __func__);
110 return HDF_FAILURE;
111 }
112 if (iface->GetUint32(obj->property, "num", &num, 0) != HDF_SUCCESS) {
113 HDF_LOGE("%s: read num fail", __func__);
114 return HDF_FAILURE;
115 }
116 pwm = (struct PwmDev *)OsalMemCalloc(sizeof(*pwm));
117 if (pwm == NULL) {
118 HDF_LOGE("%s: OsalMemCalloc pwm error", __func__);
119 return HDF_ERR_MALLOC_FAIL;
120 }
121 pwm->cfg.number = 0;
122 pwm->num = num;
123 pwm->method = &g_pwmOps;
124 pwm->busy = false;
125 ret = PwmDeviceAdd(obj, pwm);
126 if (ret != HDF_SUCCESS) {
127 HDF_LOGE("%s: error probe, ret is %d", __func__, ret);
128 OsalMemFree(pwm);
129 }
130 return ret;
131 }
132
HdfPwmRelease(struct HdfDeviceObject * obj)133 static void HdfPwmRelease(struct HdfDeviceObject *obj)
134 {
135 struct PwmDev *pwm = NULL;
136
137 HDF_LOGI("%s: entry", __func__);
138 if (obj == NULL) {
139 HDF_LOGE("%s: obj is null", __func__);
140 return;
141 }
142 pwm = (struct PwmDev *)obj->service;
143 if (pwm == NULL) {
144 HDF_LOGE("%s: pwm is null", __func__);
145 return;
146 }
147 PwmDeviceRemove(obj, pwm);
148 OsalMemFree(pwm);
149 }
150
151 struct HdfDriverEntry g_hdfPwm = {
152 .moduleVersion = 1,
153 .moduleName = "HDF_PLATFORM_PWM",
154 .Bind = HdfPwmBind,
155 .Init = HdfPwmInit,
156 .Release = HdfPwmRelease,
157 };
158
159 HDF_INIT(g_hdfPwm);
160