• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2020 HiSilicon (Shanghai) Technologies CO., LIMITED.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "pwm_hi35xx.h"
17 #include "device_resource_if.h"
18 #include "hdf_log.h"
19 #include "osal_io.h"
20 #include "osal_mem.h"
21 #include "pwm_core.h"
22 
23 #define HDF_LOG_TAG pwm_hi35xx
24 
25 struct HiPwm {
26     struct PwmDev dev;
27     volatile unsigned char *base;
28     struct HiPwmRegs *reg;
29     bool supportPolarity;
30 };
31 
HiPwmSetConfig(struct PwmDev * pwm,struct PwmConfig * config)32 int32_t HiPwmSetConfig(struct PwmDev *pwm, struct PwmConfig *config)
33 {
34     struct HiPwm *hp = (struct HiPwm *)pwm;
35     if (hp == NULL || hp->reg == NULL || config == NULL) {
36         HDF_LOGE("%s: hp reg or config is null", __func__);
37         return HDF_ERR_INVALID_PARAM;
38     }
39     if (config->polarity != PWM_NORMAL_POLARITY && config->polarity != PWM_INVERTED_POLARITY) {
40         HDF_LOGE("%s: polarity %u is invalid", __func__, config->polarity);
41         return HDF_ERR_INVALID_PARAM;
42     }
43     if (config->period < PWM_MIN_PERIOD) {
44         HDF_LOGE("%s: period %u is not support, min period %d", __func__, config->period, PWM_MIN_PERIOD);
45         return HDF_ERR_INVALID_PARAM;
46     }
47     if (config->duty < 1 || config->duty > config->period) {
48         HDF_LOGE("%s: duty %u is not support, duty must in [1, period = %u].",
49             __func__, config->duty, config->period);
50         return HDF_ERR_INVALID_PARAM;
51     }
52     HiPwmDisable(hp->reg);
53     HDF_LOGI("%s: [HiPwmDisable] done.", __func__);
54     if (pwm->cfg.polarity != config->polarity && hp->supportPolarity) {
55         HiPwmSetPolarity(hp->reg, config->polarity);
56         HDF_LOGI("%s: [HiPwmSetPolarity] done, polarity: %u -> %u.", __func__, pwm->cfg.polarity, config->polarity);
57     }
58     if (pwm->cfg.period != config->period) {
59         HiPwmSetPeriod(hp->reg, config->period);
60         HDF_LOGI("%s: [HiPwmSetPeriod] done, period: %u -> %u", __func__, pwm->cfg.period, config->period);
61     }
62     if (pwm->cfg.duty != config->duty) {
63         HiPwmSetDuty(hp->reg, config->duty);
64         HDF_LOGI("%s: [HiPwmSetDuty] done, duty: %u -> %u", __func__, pwm->cfg.duty, config->duty);
65     }
66     if (config->status == PWM_ENABLE_STATUS) {
67         if (config->number == 0) {
68             HiPwmAlwaysOutput(hp->reg);
69             HDF_LOGI("%s: [HiPwmAlwaysOutput] done, then enable.", __func__);
70         } else {
71             HiPwmOutputNumberSquareWaves(hp->reg, config->number);
72             HDF_LOGI("%s: [HiPwmOutputNumberSquareWaves] done, then enable.", __func__);
73         }
74     }
75     HDF_LOGI("%s: set PwmConfig done: number %u, period %u, duty %u, polarity %u, enable %u.",
76         __func__, config->number, config->period, config->duty, config->polarity, config->status);
77     HDF_LOGI("%s: success.", __func__);
78     return HDF_SUCCESS;
79 }
80 
81 struct PwmMethod g_pwmOps = {
82     .setConfig = HiPwmSetConfig,
83 };
84 
HiPwmRemove(struct HiPwm * hp)85 static void HiPwmRemove(struct HiPwm *hp)
86 {
87     if (hp->base != NULL) {
88         OsalIoUnmap((void *)hp->base);
89     }
90     OsalMemFree(hp);
91 }
92 
HiPwmProbe(struct HiPwm * hp,struct HdfDeviceObject * obj)93 static int32_t HiPwmProbe(struct HiPwm *hp, struct HdfDeviceObject *obj)
94 {
95     uint32_t tmp;
96     struct DeviceResourceIface *iface = NULL;
97 
98     iface = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
99     if (iface == NULL || iface->GetUint32 == NULL) {
100         HDF_LOGE("%s: face is invalid", __func__);
101         return HDF_FAILURE;
102     }
103 
104     if (iface->GetUint32(obj->property, "num", &(hp->dev.num), 0) != HDF_SUCCESS) {
105         HDF_LOGE("%s: read num fail", __func__);
106         return HDF_FAILURE;
107     }
108 
109     if (iface->GetUint32(obj->property, "base", &tmp, 0) != HDF_SUCCESS) {
110         HDF_LOGE("%s: read base fail", __func__);
111         return HDF_FAILURE;
112     }
113 
114     hp->base = OsalIoRemap(tmp, sizeof(struct HiPwmRegs));
115     if (hp->base == NULL) {
116         HDF_LOGE("%s: OsalIoRemap fail", __func__);
117         return HDF_FAILURE;
118     }
119 
120     hp->reg = (struct HiPwmRegs *)hp->base;
121     hp->supportPolarity = true;
122     hp->dev.method = &g_pwmOps;
123     hp->dev.cfg.duty = PWM_DEFAULT_DUTY_CYCLE;
124     hp->dev.cfg.period = PWM_DEFAULT_PERIOD;
125     hp->dev.cfg.polarity = PWM_DEFAULT_POLARITY;
126     hp->dev.cfg.status = PWM_DISABLE_STATUS;
127     hp->dev.cfg.number = 0;
128     hp->dev.busy = false;
129     if (PwmDeviceAdd(obj, &(hp->dev)) != HDF_SUCCESS) {
130         OsalIoUnmap((void *)hp->base);
131         HDF_LOGE("%s: [PwmDeviceAdd] failed.", __func__);
132         return HDF_FAILURE;
133     }
134     HDF_LOGI("%s: set PwmConfig: number %u, period %u, duty %u, polarity %u, enable %u.", __func__,
135         hp->dev.cfg.number, hp->dev.cfg.period, hp->dev.cfg.duty, hp->dev.cfg.polarity, hp->dev.cfg.status);
136     HDF_LOGI("%s: success.", __func__);
137 
138     return HDF_SUCCESS;
139 }
140 
HdfPwmBind(struct HdfDeviceObject * obj)141 static int32_t HdfPwmBind(struct HdfDeviceObject *obj)
142 {
143     (void)obj;
144     return HDF_SUCCESS;
145 }
146 
HdfPwmInit(struct HdfDeviceObject * obj)147 static int32_t HdfPwmInit(struct HdfDeviceObject *obj)
148 {
149     int ret;
150     struct HiPwm *hp = NULL;
151 
152     HDF_LOGI("%s: entry", __func__);
153     if (obj == NULL) {
154         HDF_LOGE("%s: obj is null", __func__);
155         return HDF_ERR_INVALID_OBJECT;
156     }
157     hp = (struct HiPwm *)OsalMemCalloc(sizeof(*hp));
158     if (hp == NULL) {
159         HDF_LOGE("%s: OsalMemCalloc hp error", __func__);
160         return HDF_ERR_MALLOC_FAIL;
161     }
162 
163     ret = HiPwmProbe(hp, obj);
164     if (ret != HDF_SUCCESS) {
165         HDF_LOGE("%s: error probe, ret is %d", __func__, ret);
166         OsalMemFree(hp);
167     }
168     return ret;
169 }
170 
HdfPwmRelease(struct HdfDeviceObject * obj)171 static void HdfPwmRelease(struct HdfDeviceObject *obj)
172 {
173     struct HiPwm *hp = NULL;
174 
175     HDF_LOGI("%s: entry", __func__);
176     if (obj == NULL) {
177         HDF_LOGE("%s: obj is null", __func__);
178         return;
179     }
180     hp = (struct HiPwm *)obj->service;
181     if (hp == NULL) {
182         HDF_LOGE("%s: hp is null", __func__);
183         return;
184     }
185     PwmDeviceRemove(obj, &(hp->dev));
186     HiPwmRemove(hp);
187 }
188 
189 struct HdfDriverEntry g_hdfPwm = {
190     .moduleVersion = 1,
191     .moduleName = "HDF_PLATFORM_PWM",
192     .Bind = HdfPwmBind,
193     .Init = HdfPwmInit,
194     .Release = HdfPwmRelease,
195 };
196 
197 HDF_INIT(g_hdfPwm);
198