• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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