1 /*
2 * Copyright (c) 2022 FuZhou Lockzhiner Electronic Co., Ltd. All rights reserved.
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 #include <stdio.h>
16 #include <stdint.h>
17
18 #include "gpio/gpio_core.h"
19 #include "device_resource_if.h"
20 #include "hdf_device_desc.h"
21 #include "hdf_log.h"
22 #include "stdio.h"
23
24 #include "lz_hardware.h"
25
26 #define PRINT_ERR(fmt, args...) do { \
27 if (1) printf("%s, %d, error: "fmt, __func__, __LINE__, ##args); \
28 } while (0)
29
30 #define PRINT_WARR(fmt, args...) do { \
31 if (1) printf("%s, %d, warr: "fmt, __func__, __LINE__, ##args); \
32 } while (0)
33
34 #define PRINT_LOG(fmt, args...) do { \
35 if (1) printf("%s, %d, log: "fmt, __func__, __LINE__, ##args); \
36 } while (0)
37
38 #define RK2206_GPIO_NAME "rk2206_gpio"
39
40 static struct GpioCntlr m_gpioCntlr;
41 static struct GpioInfo *m_gpioInfo = NULL;
42 static int32_t m_groupNum = 0;
43 static int32_t m_bitNum = 0;
44 #define GPIO_MAXSIZE 256
45 static uint8_t m_gpio_init_flag[GPIO_MAXSIZE];
46
iodrv_initgpio(uint16_t gpio)47 static int32_t iodrv_initgpio(uint16_t gpio)
48 {
49 GpioID gpio_id = (GpioID)(gpio);
50
51 if (gpio >= GPIO_MAXSIZE) {
52 PRINT_ERR("%s: gpio(%d) >= GPIO_MAXSIZE(%d)", __func__, gpio, GPIO_MAXSIZE);
53 return HDF_FAILURE;
54 }
55
56 if (m_gpio_init_flag[gpio] == 1) {
57 return HDF_SUCCESS;
58 }
59
60 PinctrlSet(gpio_id, MUX_FUNC0, PULL_KEEP, DRIVE_LEVEL0);
61 LzGpioInit(gpio_id);
62 m_gpio_init_flag[gpio] = 1;
63
64 return HDF_SUCCESS;
65 }
66
iodrv_setdir(struct GpioCntlr * cntlr,uint16_t gpio,uint16_t dir)67 static int32_t iodrv_setdir(struct GpioCntlr *cntlr, uint16_t gpio, uint16_t dir)
68 {
69 if (cntlr == NULL) {
70 PRINT_ERR("%s: cntlr is null", __func__);
71 return HDF_FAILURE;
72 }
73 if (gpio >= cntlr->count) {
74 PRINT_ERR("%s: gpio(%d) >= cntlr->count(%d)", __func__, gpio, cntlr->count);
75 return HDF_FAILURE;
76 }
77 if ((dir != GPIO_DIR_IN) && (dir != GPIO_DIR_OUT)) {
78 PRINT_ERR("%s: dir(%d) out of the range", __func__, dir);
79 return HDF_FAILURE;
80 }
81
82 GpioID gpio_id = (GpioID)(gpio);
83 LzGpioDir gpio_dir = (dir == GPIO_DIR_IN) ? (LZGPIO_DIR_IN) : (LZGPIO_DIR_OUT);
84
85 iodrv_initgpio(gpio);
86 LzGpioSetDir(gpio_id, gpio_dir);
87
88 return HDF_SUCCESS;
89 }
90
iodrv_getdir(struct GpioCntlr * cntlr,uint16_t gpio,uint16_t * dir)91 static int32_t iodrv_getdir(struct GpioCntlr *cntlr, uint16_t gpio, uint16_t *dir)
92 {
93 if (cntlr == NULL) {
94 PRINT_ERR("%s: cntlr is null", __func__);
95 return HDF_FAILURE;
96 }
97 if (gpio >= cntlr->count) {
98 PRINT_ERR("%s: gpio(%d) >= cntlr->count(%d)", __func__, gpio, cntlr->count);
99 return HDF_FAILURE;
100 }
101 if (dir == NULL) {
102 PRINT_ERR("%s: dir is null", __func__);
103 return HDF_FAILURE;
104 }
105
106 GpioID gpio_id = (GpioID)(gpio);
107 LzGpioDir gpio_dir;
108 unsigned int ret;
109
110 iodrv_initgpio(gpio);
111
112 ret = LzGpioGetDir(gpio_id, &gpio_dir);
113 if (ret != LZ_HARDWARE_SUCCESS) {
114 PRINT_ERR("%s: LzGpioGetDir error", __func__);
115 return HDF_FAILURE;
116 }
117
118 *dir = (gpio_dir == LZGPIO_DIR_IN) ? (GPIO_DIR_IN) : (GPIO_DIR_OUT);
119
120 return HDF_SUCCESS;
121 }
122
iodrv_write(struct GpioCntlr * cntlr,uint16_t gpio,uint16_t value)123 static int32_t iodrv_write(struct GpioCntlr *cntlr, uint16_t gpio, uint16_t value)
124 {
125 if (cntlr == NULL) {
126 PRINT_ERR("%s: cntlr is null", __func__);
127 return HDF_FAILURE;
128 }
129 if (gpio >= cntlr->count) {
130 PRINT_ERR("%s: gpio(%d) >= cntlr->count(%d)", __func__, gpio, cntlr->count);
131 return HDF_FAILURE;
132 }
133
134 GpioID gpio_id = (GpioID)(gpio);
135 LzGpioValue gpio_value = (value == 0) ? (LZGPIO_LEVEL_LOW) : (LZGPIO_LEVEL_HIGH);
136
137 iodrv_initgpio(gpio);
138 LzGpioSetDir(gpio_id, LZGPIO_DIR_OUT);
139 LzGpioSetVal(gpio_id, gpio_value);
140
141 return HDF_SUCCESS;
142 }
143
iodrv_read(struct GpioCntlr * cntlr,uint16_t gpio,uint16_t * value)144 static int32_t iodrv_read(struct GpioCntlr *cntlr, uint16_t gpio, uint16_t *value)
145 {
146 if (cntlr == NULL) {
147 PRINT_ERR("%s: cntlr is null", __func__);
148 return HDF_FAILURE;
149 }
150 if (gpio >= cntlr->count) {
151 PRINT_ERR("%s: gpio(%d) >= cntlr->count(%d)", __func__, gpio, cntlr->count);
152 return HDF_FAILURE;
153 }
154 if (value == NULL) {
155 PRINT_ERR("%s: value is null", __func__);
156 return HDF_FAILURE;
157 }
158
159 GpioID gpio_id = (GpioID)(gpio);
160 LzGpioValue gpio_value;
161 unsigned int ret;
162
163 iodrv_initgpio(gpio);
164
165 ret = LzGpioGetVal(gpio_id, &gpio_value);
166 if (ret != LZ_HARDWARE_SUCCESS) {
167 PRINT_ERR("%s: LzGpioGetVal error", __func__);
168 return HDF_FAILURE;
169 }
170
171 *value = (gpio_value == LZGPIO_LEVEL_LOW) ? (0) : (1);
172
173 return HDF_SUCCESS;
174 }
175
iodrv_readdrs(struct DeviceResourceNode * node,uint32_t * groupNum,uint32_t * bitNum)176 static int32_t iodrv_readdrs(struct DeviceResourceNode *node, uint32_t *groupNum, uint32_t *bitNum)
177 {
178 int32_t ret;
179 struct DeviceResourceIface *drsOps = NULL;
180
181 drsOps = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
182 if (drsOps == NULL) {
183 PRINT_ERR("%s: invalid drs ops!", __func__);
184 return HDF_FAILURE;
185 }
186 if (drsOps->GetUint32 == NULL) {
187 PRINT_ERR("%s: GetUint32 failed!", __func__);
188 return HDF_FAILURE;
189 }
190 if (groupNum == NULL) {
191 PRINT_ERR("%s: groupNum is null!", __func__);
192 return HDF_FAILURE;
193 }
194 if (bitNum == NULL) {
195 PRINT_ERR("%s: bitNum is null!", __func__);
196 return HDF_FAILURE;
197 }
198
199 ret = drsOps->GetUint32(node, "groupNum", groupNum, 0);
200 if (ret != HDF_SUCCESS) {
201 PRINT_ERR("%s: read groupNum failed!", __func__);
202 }
203
204 ret = drsOps->GetUint32(node, "bitNum", bitNum, 0);
205 if (ret != HDF_SUCCESS) {
206 PRINT_ERR("%s: read bitNum failed!", __func__);
207 }
208
209 return HDF_SUCCESS;
210 }
211
212 static struct GpioMethod m_gpio_method = {
213 .request = NULL,
214 .release = NULL,
215 .write = iodrv_write,
216 .read = iodrv_read,
217 .setDir = iodrv_setdir,
218 .getDir = iodrv_getdir,
219 .toIrq = NULL,
220 .setIrq = NULL,
221 .unsetIrq = NULL,
222 .enableIrq = NULL,
223 .disableIrq = NULL,
224 };
225
iodrv_init(struct HdfDeviceObject * device)226 static int32_t iodrv_init(struct HdfDeviceObject *device)
227 {
228 int32_t ret;
229 struct GpioCntlr *cntlr = &m_gpioCntlr;
230 uint32_t i;
231
232 PRINT_LOG("%s: Enter\n", __func__);
233 if ((device == NULL) || (device->property == NULL)) {
234 PRINT_ERR("%s: device or property is null!", __func__);
235 return HDF_ERR_INVALID_OBJECT;
236 }
237
238 ret = iodrv_readdrs(device->property, &m_groupNum, &m_bitNum);
239 if (ret != HDF_SUCCESS) {
240 PRINT_ERR("%s: read drs failed(%d)", __func__, ret);
241 return ret;
242 }
243
244 for (i = 0; i < GPIO_MAXSIZE; i++) {
245 m_gpio_init_flag[i] = 0;
246 }
247
248 m_gpioInfo = (struct GpioInfo *)OsalMemAlloc(sizeof(struct GpioInfo));
249 if (m_gpioInfo == NULL) {
250 PRINT_ERR("m_gpioInfo OsalMemAlloc failed!\n");
251 return HDF_ERR_INVALID_OBJECT;
252 }
253
254 memset_s(m_gpioInfo->name, GPIO_NAME_LEN, 0, GPIO_NAME_LEN - 1);
255 memcpy_s(m_gpioInfo->name, GPIO_NAME_LEN, RK2206_GPIO_NAME, strlen(RK2206_GPIO_NAME));
256
257 cntlr->start = 0;
258 cntlr->count = m_groupNum * m_bitNum;
259 cntlr->ops = &m_gpio_method;
260 cntlr->ginfos = &m_gpioInfo;
261 cntlr->priv = (void *)device->property;
262
263 ret = GpioCntlrAdd(cntlr);
264 if (ret != HDF_SUCCESS) {
265 PRINT_ERR("GpioCntlrAdd failed(%d)\n", ret);
266 return ret;
267 }
268
269 PRINT_LOG("gpio service: %s init success!\n", HdfDeviceGetServiceName(device));
270 return HDF_SUCCESS;
271 }
272
iodrv_release(struct HdfDeviceObject * device)273 static void iodrv_release(struct HdfDeviceObject *device)
274 {
275 struct Gpiocntlr *cntlr;
276
277 if (device == NULL) {
278 PRINT_ERR("%s: device is null", __func__);
279 return;
280 }
281
282 cntlr = GpioCntlrFromHdfDev(device);
283 if (cntlr == NULL) {
284 PRINT_ERR("%s: no service binded!\n", __func__);
285 return;
286 }
287
288 GpioCntlrRemove(cntlr);
289 PRINT_LOG("gpio service: %s release!\n", HdfDeviceGetServiceName(device));
290 }
291
iodrv_bind(struct HdfDeviceObject * device)292 static int32_t iodrv_bind(struct HdfDeviceObject *device)
293 {
294 (void)device;
295 return HDF_SUCCESS;
296 }
297
298 struct HdfDriverEntry g_gpioDriverEntry = {
299 .moduleVersion = 1,
300 .moduleName = "HDF_PLATFORM_GPIO",
301 .Bind = iodrv_bind,
302 .Init = iodrv_init,
303 .Release = iodrv_release,
304 };
305
306 HDF_INIT(g_gpioDriverEntry);
307