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