1 // Copyright (C) 2022 Beken Corporation
2 // Licensed under the Apache License, Version 2.0 (the "License");
3 // you may not use this file except in compliance with the License.
4 // You may obtain a copy of the License at
5 //
6 // http://www.apache.org/licenses/LICENSE-2.0
7 //
8 // Unless required by applicable law or agreed to in writing, software
9 // distributed under the License is distributed on an "AS IS" BASIS,
10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 // See the License for the specific language governing permissions and
12 // limitations under the License.
13
14 #include "hdf_device_desc.h"
15 #include "hdf_log.h"
16 #include "device_resource_if.h"
17 #include "gpio_core.h"
18 #include "osal_mem.h"
19
20 #include <driver/gpio.h>
21
22 #define HDF_LOG_TAG gpio_driver
23
24 struct GpioResource {
25 uint32_t pinCnt;
26
27 uint32_t pin;
28 uint32_t realPin;
29 uint32_t config;
30 };
31
32 struct GpioConfig {
33 uint32_t pin;
34 uint32_t config;
35 };
36
37 struct GpioService {
38 struct IDeviceIoService service;
39
40 struct GpioResource resource;
41 int (*test)(void);
42 };
43
44 #define INVALID_PIN 0xFFF0
45
46 #define MAX_GPIO_CNT 10
47 static struct GpioConfig g_gpioPinMap[MAX_GPIO_CNT];
48 static int g_gpioCnt;
49
50 static struct GpioService g_GpioService;
51
52 static struct GpioCntlr *g_gpioCntlr = NULL;
53
54 //static uint16_t g_simValues[MAX_GPIO_CNT] = {0};
55
GpioGetHwPin(uint16_t gpio)56 static uint32_t GpioGetHwPin(uint16_t gpio)
57 {
58 if (gpio >= g_gpioCnt)
59 return INVALID_PIN;
60
61 return g_gpioPinMap[gpio].pin;
62 }
63
GpioGetPinIdx(uint32_t pin)64 static uint32_t GpioGetPinIdx(uint32_t pin)
65 {
66 uint32_t i;
67 for (i = 0; i < g_gpioCnt; i++) {
68 if (g_gpioPinMap[i].pin == pin)
69 return i;
70 }
71
72 return INVALID_PIN;
73 }
74
GpioDevWrite(struct GpioCntlr * cntlr,uint16_t gpio,uint16_t val)75 static int32_t GpioDevWrite(struct GpioCntlr *cntlr, uint16_t gpio, uint16_t val)
76 {
77 HDF_LOGI("call %s %d", __func__, gpio);
78 if (gpio >= g_gpioCnt || g_gpioPinMap[gpio].pin == INVALID_PIN) {
79 HDF_LOGE("invalid gpio %d\n", gpio);
80 return HDF_FAILURE;
81 }
82 //g_simValues[gpio] = val;
83 if (val)
84 bk_gpio_set_output_high(GpioGetHwPin(gpio));
85 else
86 bk_gpio_set_output_low(GpioGetHwPin(gpio));
87 return HDF_SUCCESS;
88 }
GpioDevRead(struct GpioCntlr * cntlr,uint16_t gpio,uint16_t * val)89 static int32_t GpioDevRead(struct GpioCntlr *cntlr, uint16_t gpio, uint16_t *val)
90 {
91 HDF_LOGI("call %s %d", __func__, gpio);
92 //*val = g_simValues[gpio];
93 *val = bk_gpio_get_input(GpioGetHwPin(gpio));
94 return HDF_SUCCESS;
95 }
GpioDevSetDir(struct GpioCntlr * cntlr,uint16_t gpio,uint16_t dir)96 static int32_t GpioDevSetDir(struct GpioCntlr *cntlr, uint16_t gpio, uint16_t dir)
97 {
98 HDF_LOGI("call %s", __func__);
99 if (dir == GPIO_DIR_IN) {
100 bk_gpio_disable_output(GpioGetHwPin(gpio));
101 bk_gpio_enable_input(GpioGetHwPin(gpio));
102 }
103 else {
104 bk_gpio_disable_input(GpioGetHwPin(gpio));
105 bk_gpio_enable_output(GpioGetHwPin(gpio));
106 }
107
108 return HDF_SUCCESS;
109 }
GpioDevGetDir(struct GpioCntlr * cntlr,uint16_t gpio,uint16_t * dir)110 static int32_t GpioDevGetDir(struct GpioCntlr *cntlr, uint16_t gpio, uint16_t *dir)
111 {
112 HDF_LOGI("call %s", __func__);
113 // TODO
114 *dir = GPIO_DIR_IN;
115 return HDF_SUCCESS;
116 }
117
GpioIsr(gpio_id_t id)118 static void GpioIsr(gpio_id_t id)
119 {
120 uint32_t local;
121
122 local = GpioGetPinIdx(id);
123 if (local != INVALID_PIN) {
124 GpioCntlrIrqCallback(g_gpioCntlr, local);
125 }
126 }
127
GpioDevSetIrq(struct GpioCntlr * cntlr,uint16_t gpio,uint16_t mode,GpioIrqFunc func,void * arg)128 static int32_t GpioDevSetIrq(struct GpioCntlr *cntlr, uint16_t gpio, uint16_t mode, GpioIrqFunc func, void *arg)
129 {
130 gpio_config_t cfg;
131 gpio_int_type_t int_type = 0;
132
133 HDF_LOGI("call %s", __func__);
134
135 cfg.io_mode = GPIO_INPUT_ENABLE;
136 cfg.func_mode = GPIO_SECOND_FUNC_DISABLE;
137 if (mode & GPIO_IRQ_TRIGGER_RISING) {
138 int_type = GPIO_INT_TYPE_RISING_EDGE;
139 cfg.pull_mode = GPIO_PULL_DOWN_EN;
140 } else if (mode & GPIO_IRQ_TRIGGER_FALLING) {
141 int_type = GPIO_INT_TYPE_FALLING_EDGE;
142 cfg.pull_mode = GPIO_PULL_UP_EN;
143 } else if (mode & GPIO_IRQ_TRIGGER_HIGH) {
144 int_type = GPIO_INT_TYPE_HIGH_LEVEL;
145 cfg.pull_mode = GPIO_PULL_DOWN_EN;
146 } else if (mode & GPIO_IRQ_TRIGGER_LOW) {
147 int_type = GPIO_INT_TYPE_LOW_LEVEL;
148 cfg.pull_mode = GPIO_PULL_UP_EN;
149 } else {
150 return HDF_FAILURE;
151 }
152
153 bk_gpio_set_config(GpioGetHwPin(gpio), &cfg);
154 bk_gpio_set_interrupt_type(GpioGetHwPin(gpio), int_type);
155 return HDF_SUCCESS;
156 }
GpioDevUnSetIrq(struct GpioCntlr * cntlr,uint16_t gpio)157 static int32_t GpioDevUnSetIrq(struct GpioCntlr *cntlr, uint16_t gpio)
158 {
159 HDF_LOGI("call %s", __func__);
160 return HDF_SUCCESS;
161 }
GpioDevEnableIrq(struct GpioCntlr * cntlr,uint16_t gpio)162 static int32_t GpioDevEnableIrq(struct GpioCntlr *cntlr, uint16_t gpio)
163 {
164 HDF_LOGI("call %s", __func__);
165 bk_gpio_register_isr(GpioGetHwPin(gpio), GpioIsr);
166 bk_gpio_enable_interrupt(GpioGetHwPin(gpio));
167 return HDF_SUCCESS;
168 }
GpioDevDisableIrq(struct GpioCntlr * cntlr,uint16_t gpio)169 static int32_t GpioDevDisableIrq(struct GpioCntlr *cntlr, uint16_t gpio)
170 {
171 HDF_LOGI("call %s", __func__);
172 bk_gpio_disable_interrupt(GpioGetHwPin(gpio));
173 bk_gpio_register_isr(GpioGetHwPin(gpio), NULL);
174 return HDF_SUCCESS;
175 }
176
177 struct GpioMethod g_gpioMethod = {
178 .request = NULL,
179 .release = NULL,
180 .write = GpioDevWrite,
181 .read = GpioDevRead,
182 .setDir = GpioDevSetDir,
183 .getDir = GpioDevGetDir,
184 .toIrq = NULL,
185 .setIrq = GpioDevSetIrq,
186 .unsetIrq = GpioDevUnSetIrq,
187 .enableIrq = GpioDevEnableIrq,
188 .disableIrq = GpioDevDisableIrq,
189 };
190
init_pin_conifgs(void)191 static void init_pin_conifgs(void)
192 {
193 int i;
194
195 for (i = 0; i < MAX_GPIO_CNT; i++) {
196 g_gpioPinMap[i].pin = INVALID_PIN;
197 }
198 }
199
config_pin(struct GpioConfig * config)200 static int config_pin(struct GpioConfig *config)
201 {
202 if (config->config == 0) {
203 bk_gpio_disable_pull(config->pin);
204 } else if (config->config == 1) {
205 bk_gpio_pull_up(config->pin);
206 } else if (config->config == 2) {
207 bk_gpio_pull_down(config->pin);
208 } else {
209 return HDF_FAILURE;
210 }
211 return HDF_SUCCESS;
212 }
213
GetGpioDeviceResource(struct GpioService * device,const struct DeviceResourceNode * resourceNode)214 static int GetGpioDeviceResource(struct GpioService *device, const struct DeviceResourceNode *resourceNode)
215 {
216 struct DeviceResourceIface *dri = NULL;
217 struct GpioResource *resource;
218 int ret;
219
220 if (device == NULL || resourceNode == NULL) {
221 HDF_LOGE("%s: device is %p, resourceNode is %p", __func__, device, resourceNode);
222 return HDF_ERR_INVALID_PARAM;
223 }
224
225 init_pin_conifgs();
226
227 resource = &device->resource;
228
229 dri = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
230 if (dri == NULL) {
231 HDF_LOGE("DeviceResourceIface is invalid");
232 return HDF_ERR_INVALID_OBJECT;
233 }
234
235 if (dri->GetUint32(resourceNode, "pinCnt", &resource->pinCnt, 0) != HDF_SUCCESS) {
236 HDF_LOGE("Gpio config read pinCnt fail");
237 return HDF_FAILURE;
238 }
239
240 g_gpioCnt = resource->pinCnt;
241 if (g_gpioCnt > MAX_GPIO_CNT) {
242 HDF_LOGE("Gpio config pin count %d exceeds %d\n", g_gpioCnt, MAX_GPIO_CNT);
243 return HDF_FAILURE;
244 }
245
246
247 for (size_t i = 0; i < g_gpioCnt; i++) {
248 if (dri->GetUint32ArrayElem(resourceNode, "pin", i, &resource->pin, 0) != HDF_SUCCESS) {
249 HDF_LOGE("Gpio config read pin fail");
250 return HDF_FAILURE;
251 }
252 if (dri->GetUint32ArrayElem(resourceNode, "realPin", i, &resource->realPin, 0) != HDF_SUCCESS) {
253 HDF_LOGE("Gpio config read realPin fail");
254 return HDF_FAILURE;
255 }
256 if (dri->GetUint32ArrayElem(resourceNode, "config", i, &resource->config, 0) != HDF_SUCCESS) {
257 HDF_LOGE("Gpio config read config fail");
258 return HDF_FAILURE;
259 }
260 g_gpioPinMap[resource->pin].pin = resource->realPin;
261 g_gpioPinMap[resource->pin].config = resource->config;
262 HDF_LOGI("parse gpio %d : pin=%d, realPin=%d, config=%d",
263 i, resource->pin, resource->realPin, resource->config);
264
265 ret = config_pin(&g_gpioPinMap[resource->pin]);
266 if (ret) {
267 HDF_LOGE("Gpio config %d failed\n", i);
268 return HDF_FAILURE;
269 }
270 }
271
272 return HDF_SUCCESS;
273 }
274
GpioDriverBind(struct HdfDeviceObject * deviceObject)275 static int32_t GpioDriverBind(struct HdfDeviceObject *deviceObject)
276 {
277 HDF_LOGD("%s::enter, deviceObject=%p", __func__, deviceObject);
278
279 if (deviceObject == NULL) {
280 return HDF_FAILURE;
281 }
282
283 deviceObject->service = &g_GpioService.service;
284 return HDF_SUCCESS;
285 }
286
GpioDriverInit(struct HdfDeviceObject * deviceObject)287 static int32_t GpioDriverInit(struct HdfDeviceObject *deviceObject)
288 {
289 int ret;
290 struct GpioCntlr *gpioCntlr = NULL;
291
292 HDF_LOGD("%s::enter, deviceObject=%p", __func__, deviceObject);
293
294 if (deviceObject == NULL) {
295 return HDF_FAILURE;
296 }
297
298 ret = GetGpioDeviceResource(&g_GpioService, deviceObject->property);
299 if (ret != HDF_SUCCESS) {
300 HDF_LOGE("gpio parse resourcefail");
301 return HDF_FAILURE;
302 }
303
304 gpioCntlr = (struct GpioCntlr *)OsalMemCalloc(sizeof(*gpioCntlr));
305 if (gpioCntlr == NULL) {
306 HDF_LOGE("%s: malloc cntlr fail!", __func__);
307 return HDF_ERR_MALLOC_FAIL;
308 }
309
310 gpioCntlr->device.hdfDev = deviceObject;
311 gpioCntlr->start = 20;
312
313 gpioCntlr->ops = &g_gpioMethod;
314 gpioCntlr->count = g_gpioCnt;
315 ret = GpioCntlrAdd(gpioCntlr);
316 if (ret != HDF_SUCCESS) {
317 HDF_LOGE("GpioCntlrAdd fail ret=%d", ret);
318 return HDF_FAILURE;
319 }
320
321 g_gpioCntlr = gpioCntlr;
322 HDF_LOGD("%s:Init success", __func__);
323 return HDF_SUCCESS;
324 }
325
GpioDriverRelease(struct HdfDeviceObject * deviceObject)326 static void GpioDriverRelease(struct HdfDeviceObject *deviceObject)
327 {
328 HDF_LOGD("%s::enter, deviceObject=%p", __func__, deviceObject);
329 }
330
331 struct HdfDriverEntry g_GpioDriverEntry = {
332 .moduleVersion = 1,
333 .moduleName = "HDF_PLATFORM_GPIO_DRIVER",
334 .Bind = GpioDriverBind,
335 .Init = GpioDriverInit,
336 .Release = GpioDriverRelease,
337 };
338
339 HDF_INIT(g_GpioDriverEntry);
340
341