• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 HPMicro
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 <stdlib.h>
17 #include <stdio.h>
18 #include "device_resource_if.h"
19 #include "hdf_device_desc.h"
20 #include "hdf_log.h"
21 #include "osal_mem.h"
22 #include "gpio_if.h"
23 #include "gpio_core.h"
24 #include <hpm_gpio_drv.h>
25 #include <los_interrupt.h>
26 
27 #define HDF_LOG_TAG HPMICRO_GPIO_HDF
28 
29 struct HPMGpioDevice {
30     uint32_t base;
31     const char *name;
32     uint32_t port_num;
33     uint32_t irq_num;
34 };
35 
36 
Write(struct GpioCntlr * ctl,uint16_t local,uint16_t val)37 static int32_t Write(struct GpioCntlr *ctl, uint16_t local, uint16_t val)
38 {
39     struct HPMGpioDevice *hpmGpioDev = (struct HPMGpioDevice *)ctl->priv;
40     GPIO_Type *base = (GPIO_Type *)hpmGpioDev->base;
41     uint32_t port_num = hpmGpioDev->port_num;
42 
43     gpio_write_pin(base, port_num, local, (val == GPIO_VAL_LOW) ? 0 : 1);
44 
45     return HDF_SUCCESS;
46 }
47 
Read(struct GpioCntlr * ctl,uint16_t local,uint16_t * val)48 static int32_t Read(struct GpioCntlr *ctl, uint16_t local, uint16_t *val)
49 {
50     struct HPMGpioDevice *hpmGpioDev = (struct HPMGpioDevice *)ctl->priv;
51     GPIO_Type *base = (GPIO_Type *)hpmGpioDev->base;
52     uint32_t port_num = hpmGpioDev->port_num;
53 
54     if (gpio_read_pin(base, port_num, local)) {
55         *val = GPIO_VAL_HIGH;
56     } else {
57         *val = GPIO_VAL_LOW;
58     }
59 
60     return HDF_SUCCESS;
61 }
62 
SetDir(struct GpioCntlr * ctl,uint16_t local,uint16_t dir)63 int32_t SetDir(struct GpioCntlr *ctl, uint16_t local, uint16_t dir)
64 {
65     struct HPMGpioDevice *hpmGpioDev = (struct HPMGpioDevice *)ctl->priv;
66     GPIO_Type *base = (GPIO_Type *)hpmGpioDev->base;
67     uint32_t port_num = hpmGpioDev->port_num;
68 
69     if (dir == GPIO_DIR_IN) {
70         gpio_set_pin_input(base, port_num, local);
71     } else {
72         gpio_set_pin_output(base, port_num, local);
73     }
74     HDF_LOGD("GPIO: [%s-%hu] SetDir [%hu]", hpmGpioDev->name, local, dir);
75     return HDF_SUCCESS;
76 }
77 
GetDir(struct GpioCntlr * ctl,uint16_t local,uint16_t * dir)78 int32_t GetDir(struct GpioCntlr *ctl, uint16_t local, uint16_t *dir)
79 {
80     return HDF_SUCCESS;
81 }
82 
SetIrq(struct GpioCntlr * ctl,uint16_t local,uint16_t mode)83 static int32_t SetIrq(struct GpioCntlr *ctl, uint16_t local, uint16_t mode)
84 {
85     struct HPMGpioDevice *hpmGpioDev = (struct HPMGpioDevice *)ctl->priv;
86     GPIO_Type *base = (GPIO_Type *)hpmGpioDev->base;
87     uint32_t port_num = hpmGpioDev->port_num;
88 
89     if (mode & GPIO_IRQ_TRIGGER_RISING) {
90         gpio_config_pin_interrupt(base, port_num, local, gpio_interrupt_trigger_edge_rising);
91     } else if (mode & GPIO_IRQ_TRIGGER_FALLING) {
92         gpio_config_pin_interrupt(base, port_num, local, gpio_interrupt_trigger_edge_falling);
93     } else if (mode & GPIO_IRQ_TRIGGER_HIGH) {
94         gpio_config_pin_interrupt(base, port_num, local, gpio_interrupt_trigger_level_high);
95     } else if (mode & GPIO_IRQ_TRIGGER_LOW) {
96         gpio_config_pin_interrupt(base, port_num, local, gpio_interrupt_trigger_level_low);
97     } else {
98 
99     }
100 
101     return HDF_SUCCESS;
102 }
103 
UnsetIrq(struct GpioCntlr * ctl,uint16_t local)104 static int32_t UnsetIrq(struct GpioCntlr *ctl, uint16_t local)
105 {
106     return HDF_SUCCESS;
107 }
108 
EnableIrq(struct GpioCntlr * ctl,uint16_t local)109 static int32_t EnableIrq(struct GpioCntlr *ctl, uint16_t local)
110 {
111     struct HPMGpioDevice *hpmGpioDev = (struct HPMGpioDevice *)ctl->priv;
112     GPIO_Type *base = (GPIO_Type *)hpmGpioDev->base;
113     uint32_t port_num = hpmGpioDev->port_num;
114 
115     gpio_enable_pin_interrupt(base, port_num, local);
116 
117     return HDF_SUCCESS;
118 }
119 
DisableIrq(struct GpioCntlr * ctl,uint16_t local)120 static int32_t DisableIrq(struct GpioCntlr *ctl, uint16_t local)
121 {
122     struct HPMGpioDevice *hpmGpioDev = (struct HPMGpioDevice *)ctl->priv;
123     GPIO_Type *base = (GPIO_Type *)hpmGpioDev->base;
124     uint32_t port_num = hpmGpioDev->port_num;
125 
126     gpio_disable_pin_interrupt(base, port_num, local);
127 
128     return HDF_SUCCESS;
129 }
130 
131 static struct GpioMethod gpioOps = {
132     .write = Write,
133     .read = Read,
134     .setDir = SetDir,
135     .getDir = GetDir,
136     .setIrq = SetIrq,
137     .unsetIrq = UnsetIrq,
138     .enableIrq = EnableIrq,
139     .disableIrq = DisableIrq,
140 };
141 
GpioHcsResurceInit(struct GpioCntlr * ctl)142 static int32_t GpioHcsResurceInit(struct GpioCntlr *ctl)
143 {
144     int ret = HDF_SUCCESS;
145     struct HdfDeviceObject *device = ctl->device.hdfDev;
146     struct HPMGpioDevice *hpmGpioDev = (struct HPMGpioDevice *)ctl->priv;
147 
148     struct DeviceResourceIface *dri = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
149     if (dri == NULL) {
150         HDF_LOGE("get DeviceResourceIface Failed!!!");
151         return HDF_FAILURE;
152     }
153 
154     dri->GetUint32(device->property, "base", &hpmGpioDev->base, 0);
155     dri->GetString(device->property, "name", &hpmGpioDev->name, NULL);
156     dri->GetUint32(device->property, "port_num", &hpmGpioDev->port_num, 0);
157     dri->GetUint32(device->property, "irq_num", &hpmGpioDev->irq_num, 0);
158     dri->GetUint16(device->property, "count", &ctl->count, 0);
159     ctl->start = ctl->count * hpmGpioDev->port_num;
160 
161     HDF_LOGI("GPIO: base: 0x%X", hpmGpioDev->base);
162     HDF_LOGI("GPIO: name: %s", hpmGpioDev->name);
163     HDF_LOGI("GPIO: port_num: %u", hpmGpioDev->port_num);
164     HDF_LOGI("GPIO: irq_num: %u", hpmGpioDev->irq_num);
165     HDF_LOGI("GPIO: count: %u", ctl->count);
166     HDF_LOGI("GPIO: start: %u", ctl->start);
167 
168     return ret;
169 }
170 
hpm_gpio_isr(VOID * parm)171 static __attribute__((section(".interrupt.text"))) VOID hpm_gpio_isr(VOID *parm)
172 {
173     struct GpioCntlr *ctl = (struct GpioCntlr *)parm;
174     struct HPMGpioDevice *hpmGpioDev = (struct HPMGpioDevice *)ctl->priv;
175     GPIO_Type *base = (GPIO_Type *)hpmGpioDev->base;
176     uint32_t port_num = hpmGpioDev->port_num;
177 
178     for (uint32_t local = 0; local < ctl->count; local++) {
179         if (gpio_check_clear_interrupt_flag(base, port_num, local)) {
180             GpioCntlrIrqCallback(ctl, local);
181         }
182     }
183 }
184 
GpioDriverBind(struct HdfDeviceObject * device)185 static int32_t GpioDriverBind(struct HdfDeviceObject *device)
186 {
187     HDF_LOGI("Bind: It's not to be run");
188     return HDF_SUCCESS;
189 }
190 
GpioDriverInit(struct HdfDeviceObject * device)191 static int32_t GpioDriverInit(struct HdfDeviceObject *device)
192 {
193     int32_t ret = HDF_SUCCESS;
194     struct HPMGpioDevice *hpmGpioDev;
195     struct GpioCntlr *ctl = (struct GpioCntlr *)OsalMemCalloc(sizeof(struct GpioCntlr) + sizeof(struct HPMGpioDevice));
196     ctl->priv = (char *)ctl + sizeof(struct GpioCntlr);
197     hpmGpioDev = (struct HPMGpioDevice *)ctl->priv;
198     ctl->ops = &gpioOps;
199 
200     PlatformDeviceSetHdfDev(&ctl->device, device);
201 
202     ret = GpioHcsResurceInit(ctl);
203     if (ret) {
204         HDF_LOGE("Init: GpioHcsResurceInit Failed!!!\n");
205         goto ERROR;
206     }
207 
208     ret = GpioCntlrAdd(ctl);
209     if (ret) {
210         HDF_LOGE("Init: GpioCntlrAdd Fualed, name: %s!!!\n", hpmGpioDev->name);
211         goto ERROR;
212     }
213 
214     HwiIrqParam irqParam;
215     irqParam.pDevId = ctl;
216     LOS_HwiCreate(HPM2LITEOS_IRQ(hpmGpioDev->irq_num), 1, 0, (HWI_PROC_FUNC)hpm_gpio_isr, &irqParam);
217     LOS_HwiEnable(HPM2LITEOS_IRQ(hpmGpioDev->irq_num));
218 
219     HDF_LOGI("Init");
220 
221     return ret;
222 
223 ERROR:
224     OsalMemFree(ctl);
225     return ret;
226 }
227 
GpioDriverRelease(struct HdfDeviceObject * device)228 static void GpioDriverRelease(struct HdfDeviceObject *device)
229 {
230     if (device == NULL) {
231         return;
232     }
233 
234     struct GpioCntlr *ctl = GpioCntlrFromHdfDev(device);
235     if (ctl) {
236         OsalMemFree(ctl);
237     }
238     HDF_LOGI("Release");
239     return;
240 }
241 
242 
243 struct HdfDriverEntry g_gpioDriverEntry = {
244     .moduleVersion = 1,
245     .moduleName = "HPMICRO_GPIO_MODULE_HDF",
246     .Bind = GpioDriverBind,
247     .Init = GpioDriverInit,
248     .Release = GpioDriverRelease,
249 };
250 
251 HDF_INIT(g_gpioDriverEntry);
252